package org.ihtsdo.otf.mapping.jpa.handlers;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.ihtsdo.otf.mapping.jpa.services.ContentServiceJpa;
import org.ihtsdo.otf.mapping.jpa.services.MetadataServiceJpa;
import org.ihtsdo.otf.mapping.rf2.Concept;
import org.ihtsdo.otf.mapping.rf2.TreePosition;
import org.ihtsdo.otf.mapping.services.ContentService;
import org.ihtsdo.otf.mapping.services.MetadataService;

/**
 * GMDN project specific algorithm handler.
 */
public class IcdoProjectSpecificAlgorithmHandler extends
    DefaultProjectSpecificAlgorithmHandler {

  /** The term type. */
  private static Long termType = null;

  /* see superclass */
  @Override
  public boolean isTargetCodeValid(String terminologyId) throws Exception {

    if (!terminologyId.contains("/")) {
      return false;
    }
    // Cache the "Term" term type - valid codes require it
    cacheTermType(mapProject.getDestinationTerminology(),
        mapProject.getDestinationTerminologyVersion());

    final ContentService contentService = new ContentServiceJpa();
    try {
      // Concept must exist
      final Concept concept =
          contentService.getConcept(terminologyId,
              mapProject.getDestinationTerminology(),
              mapProject.getDestinationTerminologyVersion());

      return concept != null;

    } catch (Exception e) {
      throw e;
    } finally {
      contentService.close();
    }
  }

  /**
   * Cache term type.
   *
   * @param terminology the terminology
   * @param version the version
   * @throws Exception the exception
   */
  private static void cacheTermType(String terminology, String version)
    throws Exception {
    // lazy initialize
    if (termType == null) {
      final MetadataService service = new MetadataServiceJpa();
      try {
        for (final Map.Entry<String, String> entry : service
            .getDescriptionTypes(terminology, version).entrySet()) {
          if (entry.getValue().equals("Term")) {
            termType = Long.valueOf(entry.getKey());
          }
        }

      } catch (Exception e) {
        throw e;
      } finally {
        service.close();
      }
    }
  }

  /* see superclass */
  @Override
  public List<TreePosition> limitTreePositions(List<TreePosition> treePositions) {
    // If the tree structure has more than say 100 positions, just return the
    // top one from each root
    List<TreePosition> result = new ArrayList<TreePosition>();
    if (countTreePositions(treePositions) > 100) {
      for (final TreePosition treePosition : treePositions) {
        stripTreePosition(treePosition);
        result.add(treePosition);
      }
    } else {
      return treePositions;
    }

    return result;
  }

  /**
   * Count tree positions.
   *
   * @param treePositions the tps
   * @return the int
   */
  private int countTreePositions(List<TreePosition> treePositions) {
    int i = 0;
    for (final TreePosition treePosition : treePositions) {
      i++;
      i += countTreePositions(treePosition.getChildren());
    }

    return i;

  }

  /**
   * Strip tree position.
   *
   * @param treePosition the tree position
   */
  private void stripTreePosition(TreePosition treePosition) {
    if (treePosition.getChildren().size() > 1) {
      final TreePosition firstChild = treePosition.getChildren().get(0);
      treePosition.getChildren().clear();
      treePosition.getChildren().add(firstChild);
    }
    for (final TreePosition child : treePosition.getChildren()) {
      stripTreePosition(child);
    }
  }

}

@@ -545,16 +545,20 @@
 dler
+%0A   
  extends
 %0A   
@@ -553,20 +553,16 @@
  extends
-%0A   
  Default
@@ -600,72 +600,8 @@
  %7B%0A%0A
-  /** The term type. */%0A  private static Long termType = null;%0A%0A
   /*
@@ -1082,26 +1082,16 @@
 oncept =
-%0A         
  content
@@ -1126,36 +1126,32 @@
 gyId,%0A          
-    
 mapProject.getDe
@@ -1170,28 +1170,24 @@
 minology(),%0A
-    
           ma
@@ -1368,742 +1368,8 @@
  %7D%0A%0A
-  /**%0A   * Cache term type.%0A   *%0A   * @param terminology the terminology%0A   * @param version the version%0A   * @throws Exception the exception%0A   */%0A  private static void cacheTermType(String terminology, String version)%0A    throws Exception %7B%0A    // lazy initialize%0A    if (termType == null) %7B%0A      final MetadataService service = new MetadataServiceJpa();%0A      try %7B%0A        for (final Map.Entry%3CString, String%3E entry : service%0A            .getDescriptionTypes(terminology, version).entrySet()) %7B%0A          if (entry.getValue().equals(%22Term%22)) %7B%0A            termType = Long.valueOf(entry.getKey());%0A          %7D%0A        %7D%0A%0A      %7D catch (Exception e) %7B%0A        throw e;%0A      %7D finally %7B%0A        service.close();%0A      %7D%0A    %7D%0A  %7D%0A%0A
   /*
@@ -1438,32 +1438,37 @@
 itTreePositions(
+%0A    
 List%3CTreePositio

fix ICDO performance search bug.