package category;

import datastructures.set.CustomSet;
import abstraction.CustomSetPersistenceDecorator;
import abstraction.PersistenceAdapter;
import exeptions.CategoryAlreadyExists;
import exeptions.CategroyDoesNotExist;
import exeptions.NonUniqueId;

import java.util.Optional;
import java.util.Set;

public class CategoryRepository {

	final private CustomSet<Category> categories;

	public CategoryRepository(PersistenceAdapter<Category> categoryPersistenceAdapter) {
		this.categories = new CustomSetPersistenceDecorator<Category>(categoryPersistenceAdapter);
	}

	public Optional<Category> getByName(CategoryName name) {
		return categories.find(category -> category.getName().equals(name));
	}

	public CategoryId getIdByName(CategoryName name) {

		return getByName(name)
				.orElseThrow(() -> new CategroyDoesNotExist("A Category with name " + name + " does not exits. You must create it first."))
				.getId();
	}

	public Optional<Category> getById(CategoryId id) {
		return categories.find(category -> category.getId().equals(id));
	}

	public Set<Category> getAll() {
		return categories.getSet();
	}

	public void add(Category category) {
		checkDuplicates(category);
		categories.add(category);
	}

	/**
	 * Check for duplicates with the domain rules
	 *
	 * @param category
	 */
	private void checkDuplicates(Category category) {
		if (this.getByName(category.getName()).isPresent()) {
			throw new CategoryAlreadyExists("A category with the name " + category.getName() + " already exits.");
		}

		if (this.getById(category.getId()).isPresent()) {
			throw new NonUniqueId("A category with the id " + category.getId() + " already exits.");
		}
	}
}
