package org.ihtsdo.otf.mapping.mojo;

import java.util.List;

import org.apache.log4j.Logger;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.ihtsdo.otf.mapping.helpers.MapProjectList;
import org.ihtsdo.otf.mapping.jpa.MapProjectJpa;
import org.ihtsdo.otf.mapping.jpa.services.MappingServiceJpa;
import org.ihtsdo.otf.mapping.jpa.services.WorkflowServiceJpa;
import org.ihtsdo.otf.mapping.model.MapProject;
import org.ihtsdo.otf.mapping.services.MappingService;
import org.ihtsdo.otf.mapping.services.WorkflowService;

/**
 * Mojo to transform targets of a source mapping project into scope concepts for
 * another mapping project. i.e. from MedDRA to SNOMED -> SNOMED to MedDRA
 * 
 * See admin/loader/pom.xml for a sample execution
 *
 * @goal target-to-scope-concept
 */
public class TargetMappingToScopedConceptMojo extends AbstractMojo {

  /**
   * Name of source mapping project to retrieve targets
   * 
   * @parameter
   * @required
   */
  private String sourceMapProjectName;

  /**
   * Name of target mapping project to create scoped concepts
   * 
   * @parameter
   * @required
   */
  private String targetMapProjectName;

  public void execute() throws MojoExecutionException, MojoFailureException {

    try {
      doWork();
    } catch (MojoExecutionException me) {
      throw me;
    } catch (Exception e) {
      throw new MojoExecutionException("Mojo failed to execute.");
    }
  }

  private void doWork() throws Exception {

    MapProject sourceMapProject = new MapProjectJpa();
    MapProject targetMapProject = new MapProjectJpa();

    // get target ids from MED-to-SCT that are ready for publication.
    try (MappingService mappingService = new MappingServiceJpa();
        WorkflowService workflowService = new WorkflowServiceJpa()) {

      final MapProjectList mapProjectList = mappingService.getMapProjects();
      for (MapProject mapProject : mapProjectList.getMapProjects()) {
        if (mapProject.getName().equals(sourceMapProjectName)) {
          sourceMapProject = mapProject;
          break;
        }
      }

      for (MapProject mapProject : mapProjectList.getMapProjects()) {
        if (mapProject.getName().equals(targetMapProjectName)) {
          targetMapProject = mapProject;
          break;
        }
      }

      if (sourceMapProject.getId() == null) {
        throw new MojoExecutionException(
            "Source project name not found.  Please verify parameters.");
      }

      if (targetMapProject.getId() == null) {
        throw new MojoExecutionException(
            "Target project name not found.  Please verify parameters.");
      }

      final List<String> newScopeConceptList = mappingService
          .getTargetCodeForReadyForPublication(sourceMapProject.getId());

      if (newScopeConceptList != null && !newScopeConceptList.isEmpty()) {
        // upload code as scope concepts to other project
        for (String oldScopedConcept : targetMapProject.getScopeConcepts()) {
          targetMapProject.removeScopeConcept(oldScopedConcept);
        }
        for (String newScopedConcept : newScopeConceptList) {
          targetMapProject.addScopeConcept(newScopedConcept);
        }

        // recompute workflow
        Logger.getLogger(getClass()).info("Computing workflow for "
            + targetMapProject.getName() + ", " + targetMapProject.getId());
        workflowService.computeWorkflow(targetMapProject);
      }

      Logger.getLogger(getClass())
          .info("Complete loading scoped concepts to target map project");

    } catch (Exception e) {
      Logger.getLogger(getClass()).error(
          "ERROR occured during processing of scoped concepts between map projects.",
          e);
      throw e;
    }

  }

}

@@ -48,19 +48,67 @@
 va.util.
-Lis
+HashSet;%0Aimport java.util.List;%0Aimport java.util.Se
 t;%0A%0Aimpo
@@ -1392,22 +1392,24 @@
 %7B%0A      
-doWork
+transfer
 ();%0A    
@@ -1587,14 +1587,16 @@
 oid 
-doWork
+transfer
 () t
@@ -3054,26 +3054,32 @@
        f
-or (
+inal Set%3C
 String
+%3E
  oldScop
@@ -3087,18 +3087,49 @@
 dConcept
+List = new HashSet%3C%3E(%0A          
  
-:
  targetM
@@ -3161,147 +3161,478 @@
 s())
- %7B%0A          targetMapProject.removeScopeConcept(oldScopedConcept);%0A        %7D%0A        for (String newScopedConcept : newScopeConceptList) %7B
+;%0A%0A        for (String oldScopedConcept : oldScopedConceptList) %7B%0A          Logger.getLogger(getClass()).info(%22Removing scoped concept %22%0A              + oldScopedConcept + %22 from target map project.%22);%0A          targetMapProject.removeScopeConcept(oldScopedConcept);%0A        %7D%0A        for (String newScopedConcept : newScopeConceptList) %7B%0A          Logger.getLogger(getClass()).info(%22Adding scoped concept %22%0A              + newScopedConcept + %22 to target map project.%22);
 %0A   

Fix java concurrency error when deleting scoped concepts in target mapping project.