<commit_before>package beaform.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import beaform.entities.Formula;
import beaform.entities.FormulaTag;
import beaform.entities.Ingredient;

/**
 * This class handles all DB access for formulas.
 *
 * @author <NAME>
 *
 */
public final class FormulaDAO {

	private static final Logger LOG = LoggerFactory.getLogger(FormulaDAO.class);

	/** Query to search for a formula by tag */
	private static final String FORMULA_BY_TAG = "MATCH (t:FormulaTag { name:{name} })<-[r]-(f:Formula) RETURN f";

	private FormulaDAO() {
		// private constructor, because this is a utility class.
	}

	public static List<Ingredient> getIngredients(final Formula formula) {

		final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
		entityManager.getTransaction().begin();
		final Formula retrievedFormula = entityManager.find(Formula.class, formula.getName());
		final List<Ingredient> retList = retrievedFormula.getIngredients();

		entityManager.getTransaction().commit();

		return retList;
	}

	public static void updateExisting(final String name,
	                                  final String description,
	                                  final String totalAmount,
	                                  final List<Ingredient> ingredients,
	                                  final List<FormulaTag> tags) {

		final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
		entityManager.getTransaction().begin();

		final Formula formula = entityManager.find(Formula.class, name);

		setFormulaProperties(formula, description, totalAmount);

		clearFormulaRelations(formula);

		addTags(tags, formula);
		addIngredientsToFormula(formula, ingredients);

		entityManager.getTransaction().commit();
		entityManager.detach(formula);
	}

	private static void addIngredientsToFormula(final Formula formula, final List<Ingredient> ingredients) {
		for (final Ingredient ingredient : ingredients) {
			// We should only be holding existing Formulas at this point
			formula.addIngredient(ingredient.getFormula(), ingredient.getAmount());
		}
	}

	public static void addFormula(final String name,
	                              final String description,
	                              final String totalAmount,
	                              final List<Ingredient> ingredients,
	                              final List<FormulaTag> tags) {

		final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
		entityManager.getTransaction().begin();

		final Formula formula = new Formula(name, description, totalAmount);

		addTags(tags, formula);
		addIngredientsToFormula(formula, ingredients);

		entityManager.persist(formula);
		entityManager.getTransaction().commit();
		entityManager.detach(formula);

	}

	private static void setFormulaProperties(final Formula formula, final String description, final String totalAmount) {
		formula.setDescription(description);
		formula.setTotalAmount(totalAmount);
	}

	/**
	 * This method adds tags to a formula.
	 * It assumes a running transaction.<commit_msg>Clear the enitymanager to avoid duplicate objects<commit_after>package beaform.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import beaform.entities.Formula;
import beaform.entities.FormulaTag;
import beaform.entities.Ingredient;

/**
 * This class handles all DB access for formulas.
 *
 * @author <NAME>
 *
 */
public final class FormulaDAO {

	private static final Logger LOG = LoggerFactory.getLogger(FormulaDAO.class);

	/** Query to search for a formula by tag */
	private static final String FORMULA_BY_TAG = "MATCH (t:FormulaTag { name:{name} })<-[r]-(f:Formula) RETURN f";

	private FormulaDAO() {
		// private constructor, because this is a utility class.
	}

	public static List<Ingredient> getIngredients(final Formula formula) {

		final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
		entityManager.getTransaction().begin();
		final Formula retrievedFormula = entityManager.find(Formula.class, formula.getName());
		final List<Ingredient> retList = retrievedFormula.getIngredients();

		entityManager.getTransaction().commit();
		entityManager.clear();

		return retList;
	}

	public static void updateExisting(final String name,
	                                  final String description,
	                                  final String totalAmount,
	                                  final List<Ingredient> ingredients,
	                                  final List<FormulaTag> tags) {

		final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
		entityManager.getTransaction().begin();

		final Formula formula = entityManager.find(Formula.class, name);

		setFormulaProperties(formula, description, totalAmount);

		clearFormulaRelations(formula);

		addTags(tags, formula);
		addIngredientsToFormula(formula, ingredients);

		entityManager.getTransaction().commit();
		entityManager.detach(formula);
	}

	private static void addIngredientsToFormula(final Formula formula, final List<Ingredient> ingredients) {
		for (final Ingredient ingredient : ingredients) {
			final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
			final Formula dbVersion = entityManager.find(Formula.class, ingredient.getFormula().getName());
			final Formula toAdd;
			if (dbVersion != null) {
				toAdd = dbVersion;
			}
			else {
				toAdd = ingredient.getFormula();
			}
			formula.addIngredient(toAdd, ingredient.getAmount());
		}
	}

	public static void addFormula(final String name,
	                              final String description,
	                              final String totalAmount,
	                              final List<Ingredient> ingredients,
	                              final List<FormulaTag> tags) {

		final EntityManager entityManager = GraphDbHandler.getInstance().getEntityManager();
		entityManager.getTransaction().begin();

		final Formula formula = new Formula(name, description, totalAmount);

		addTags(tags, formula);
		addIngredientsToFormula(formula, ingredients);

		entityManager.persist(formula);
		entityManager.getTransaction().commit();
		entityManager.detach(formula);
		entityManager.clear();

	}

	private static void setFormulaProperties(final Formula formula, final String description, final String totalAmount) {
		formula.setDescription(description);
		formula.setTotalAmount(totalAmount);
	}

	/**
	 * This method adds tags to a formula.
	 * It assumes a running transaction.
{'fraction_non_alphanumeric': 0.0911551061102407, 'fraction_numerical': 0.0005697194131890044, 'mean_word_length': 3.7222595830531273, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2647985', 'n_tokens_mistral': 2004, 'n_tokens_neox': 1813, 'n_words': 463}