/*
 *    Copyright 2015 West Coast Informatics, LLC
 */
package com.wci.umls.server.jpa.algo.insert;

import java.io.File;
import java.util.List;
import java.util.Properties;
import java.util.UUID;

import javax.persistence.NoResultException;

import com.wci.umls.server.AlgorithmParameter;
import com.wci.umls.server.ProcessExecution;
import com.wci.umls.server.ValidationResult;
import com.wci.umls.server.helpers.ConfigUtility;
import com.wci.umls.server.helpers.LocalException;
import com.wci.umls.server.jpa.ValidationResultJpa;
import com.wci.umls.server.jpa.algo.AbstractInsertMaintReleaseAlgorithm;

/**
 * Implementation of an algorithm to save information before an insertion.
 */
public class PreInsertionAlgorithm extends AbstractInsertMaintReleaseAlgorithm {

  /**
   * Instantiates an empty {@link PreInsertionAlgorithm}.
   * @throws Exception if anything goes wrong
   */
  public PreInsertionAlgorithm() throws Exception {
    super();
    setActivityId(UUID.randomUUID().toString());
    setWorkId("PREINSERTION");
    setLastModifiedBy("admin");
  }

  /**
   * Check preconditions.
   *
   * @return the validation result
   * @throws Exception the exception
   */
  /* see superclass */
  @Override
  public ValidationResult checkPreconditions() throws Exception {

    ValidationResult validationResult = new ValidationResultJpa();

    if (getProject() == null) {
      throw new LocalException("Pre Insertion requires a project to be set");
    }

    // Go through all the files needed by insertion and check for presence
    // Check the input directories
    final String srcFullPath =
        ConfigUtility.getConfigProperties().getProperty("source.data.dir") + "/"
            + getProcess().getInputPath();

    setSrcDirFile(new File(srcFullPath));
    if (!getSrcDirFile().exists()) {
      throw new LocalException(
          "Specified input directory does not exist - " + srcFullPath);
    }

    checkFileExist(srcFullPath, "attributes.src");
    checkFileExist(srcFullPath, "classes_atoms.src");
    checkFileExist(srcFullPath, "contexts.src");
    checkFileExist(srcFullPath, "mergefacts.src");
    checkFileExist(srcFullPath, "MRDOC.RRF");
    checkFileExist(srcFullPath, "relationships.src  ");
    checkFileExist(srcFullPath, "sources.src");
    checkFileExist(srcFullPath, "termgroups.src");

    return validationResult;
  }

  /**
   * Check file exist.
   *
   * @param srcFullPath the src full path
   * @param fileName the file name
   * @throws Exception the exception
   */
  @SuppressWarnings("static-method")
  private void checkFileExist(String srcFullPath, String fileName)
    throws Exception {

    File sourceFile = new File(srcFullPath + File.separator + fileName);
    if (!sourceFile.exists()) {
      throw new Exception(fileName
          + " file doesn't exist at specified input directory: " + srcFullPath);
    }

  }

  /**
   * Compute.
   *
   * @throws Exception the exception
   */
  /* see superclass */
  @Override
  public void compute() throws Exception {
    logInfo("Starting " + getName());

    // No Molecular actions will be generated by this algorithm
    setMolecularActionFlag(false);

    // Populate the executionInfo map of the process' execution.
    ProcessExecution processExecution = getProcess();

    // Get the max atom Id prior to the insertion starting (used to identify
    // which atoms are new)
    Long atomId = null;
    try {
      final javax.persistence.Query query =
          manager.createQuery("select max(a.id) from AtomJpa a ");
      final Long atomId2 = (Long) query.getSingleResult();
      atomId = atomId2 != null ? atomId2 : atomId;
    } catch (NoResultException e) {
      atomId = 0L;
    }
    processExecution.getExecutionInfo().put("maxAtomIdPreInsertion",
        atomId.toString());
    logInfo(" maxAtomIdPreInsertion = "
        + processExecution.getExecutionInfo().get("maxAtomIdPreInsertion"));
    commitClearBegin();

    // Get the max AUI prior to the insertion starting (used to identify
    // newly created AUIs)
    Long AUI = null;
    try {
      final javax.persistence.Query query =
          manager.createQuery("select max(a.id) from AtomIdentityJpa a ");
      final Long AUI2 = (Long) query.getSingleResult();
      AUI = AUI2 != null ? AUI2 : AUI;
    } catch (NoResultException e) {
      AUI = 0L;
    }
    processExecution.getExecutionInfo().put("maxAUIPreInsertion",
        AUI.toString());
    logInfo(" maxAUIPreInsertion = "
        + processExecution.getExecutionInfo().get("maxAUIPreInsertion"));
    commitClearBegin();

    // Get the max Semantic Type Component Id prior to the insertion starting
    Long styId = null;
    try {
      final javax.persistence.Query query = manager
          .createQuery("select max(a.id) from SemanticTypeComponentJpa a ");
      final Long styId2 = (Long) query.getSingleResult();
      styId = styId2 != null ? styId2 : styId;
    } catch (NoResultException e) {
      styId = 0L;
    }
    processExecution.getExecutionInfo().put("maxStyIdPreInsertion",
        styId.toString());
    logInfo(" maxStyIdPreInsertion = "
        + processExecution.getExecutionInfo().get("maxStyIdPreInsertion"));

    // Get the max MapSet Id prior to the insertion starting
    Long mapSetId = null;
    try {
      final javax.persistence.Query query =
          manager.createQuery("select max(a.id) from MapSetJpa a ");
      final Long mapSetId2 = (Long) query.getSingleResult();
      mapSetId = mapSetId2 != null ? mapSetId2 : mapSetId;
    } catch (NoResultException e) {
      mapSetId = 0L;
    }
    processExecution.getExecutionInfo().put("maxMapSetIdPreInsertion",
        mapSetId.toString());
    logInfo(" maxMapSetIdPreInsertion = "
        + processExecution.getExecutionInfo().get("maxMapSetIdPreInsertion"));

    // Get the max Atom Subset Id prior to the insertion starting
    Long atomSubsetId = null;
    try {
      final javax.persistence.Query query =
          manager.createQuery("select max(a.id) from AtomSubsetJpa a ");
      final Long atomSubsetId2 = (Long) query.getSingleResult();
      atomSubsetId = atomSubsetId2 != null ? atomSubsetId2 : atomSubsetId;
    } catch (NoResultException e) {
      atomSubsetId = 0L;
    }
    processExecution.getExecutionInfo().put("maxAtomSubsetIdPreInsertion",
        atomSubsetId.toString());
    logInfo(" maxAtomSubsetIdPreInsertion = " + processExecution
        .getExecutionInfo().get("maxAtomSubsetIdPreInsertion"));

    // Get the max Concept Subset Id prior to the insertion starting
    Long conceptSubsetId = null;
    try {
      final javax.persistence.Query query =
          manager.createQuery("select max(a.id) from ConceptSubsetJpa a ");
      final Long conceptSubsetId2 = (Long) query.getSingleResult();
      conceptSubsetId =
          conceptSubsetId2 != null ? conceptSubsetId2 : conceptSubsetId;
    } catch (NoResultException e) {
      conceptSubsetId = 0L;
    }
    processExecution.getExecutionInfo().put("maxConceptSubsetIdPreInsertion",
        conceptSubsetId.toString());
    logInfo(" maxConceptSubsetIdPreInsertion = " + processExecution
        .getExecutionInfo().get("maxConceptSubsetIdPreInsertion"));

    // NOTE: the processExecution is updated by the calling method,
    // typically RunProcessAsThread in ProcessServiceRestImpl

    logInfo("Finished " + getName());
  }

  /**
   * Reset.
   *
   * @throws Exception the exception
   */
  /* see superclass */
  @Override
  public void reset() throws Exception {
    logInfo("Starting RESET " + getName());
    // n/a - No reset
    logInfo("Finished RESET " + getName());  }

  /* see superclass */
  @Override
  public void checkProperties(Properties p) throws Exception {
    // n/a
  }

  /* see superclass */
  @Override
  public void setProperties(Properties p) throws Exception {
    // n/a
  }

  /* see superclass */
  @Override
  public List<AlgorithmParameter> getParameters() throws Exception {
    final List<AlgorithmParameter> params = super.getParameters();

    return params;
  }

  @Override
  public String getDescription() {
    return "Prepares an insertion to operate and validates starting conditions.";
  }
}
@@ -2223,18 +2223,16 @@
 hips.src
-  
 %22);%0A    

Fix bug in relationships.src file name in PreInsertionAlgorithm.