package mi.hdm.recipes;

import mi.hdm.exceptions.InvalidIngredientException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

//TODO: make this not a singleton?
public class IngredientManager {
    private static final Logger log = LogManager.getLogger(IngredientManager.class);
    private static final IngredientManager instance = new IngredientManager();

    private final List<Ingredient> allIngredients;

    private IngredientManager() {
        allIngredients = new ArrayList<>();
    }

    public static IngredientManager getInstance() {
        return instance;
    }

    /**
     * Adds an ingredient if there is no equal ingredient (no ingredient with the same name).
     * @param in Ingredient that is to be added
     * @return True if the ingredient has been added (meaning no equal ingredient existed before), otherwise false.
     */
    public boolean addIngredient(Ingredient in) {
        if (getIngredientByName(in.getName()).isPresent()) {
            log.error("Ingredient {} not added because it already exists.", in.getName());
            return false;
            //TODO: Exception or false?
        } else {
            log.info("Ingredient {} added successfully.", in.getName());
            allIngredients.add(in);
            return true;
        }
    }

    public boolean addIngredient(Measurement unit, String name, NutritionTable nutritionTable) {
        Ingredient in = new Ingredient(unit, name, nutritionTable);
        return addIngredient(in);
    }

    public Ingredient deleteIngredient(int i) {
        log.info("Ingredient {} deleted successfully.", allIngredients.get(i).getName());
        return allIngredients.remove(i);
    }

    public boolean deleteIngredient(String name) {
        //TODO: check this out, might be a better solution
        /*Optional<Ingredient> ingredient = getIngredientByName(name);
        return ingredient.isPresent() && allIngredients.remove(ingredient);*/

        Ingredient ingredient = getIngredientByName(name).orElseThrow(() -> new InvalidIngredientException("No ingredient with name " + name));
        log.info("Ingredient {} deleted successfully.", name);
        return allIngredients.remove(ingredient);
    }

    public void clearIngredients() {
        log.info("List allIngredients cleared successfully.");
        allIngredients.clear();
    }

    public List<Ingredient> getAllIngredients() {
        return allIngredients;
    }

    private Optional<Ingredient> getIngredientByName(String name) {
        for (final Ingredient i : allIngredients) {
            if (name.equals(i.getName())) {
                return Optional.of(i);
            }
        }
        return Optional.empty();
    }
}