/*
 *    Copyright 2016 West Coast Informatics, LLC
 */
package com.wci.umls.server.jpa.services.validation;

import java.util.List;
import java.util.Properties;

import com.wci.umls.server.Project;
import com.wci.umls.server.ValidationResult;
import com.wci.umls.server.algo.action.MolecularActionAlgorithm;
import com.wci.umls.server.jpa.ValidationResultJpa;
import com.wci.umls.server.jpa.algo.action.AbstractMolecularAction;
import com.wci.umls.server.jpa.algo.action.MergeMolecularAction;
import com.wci.umls.server.jpa.algo.action.MoveMolecularAction;
import com.wci.umls.server.model.content.Atom;
import com.wci.umls.server.model.content.Concept;
import com.wci.umls.server.services.ContentService;

/**
 * Validates merges between two {@link Concept}s that were published previously
 * with different CUIs.
 */
public class MGV_A4 extends AbstractValidationCheck {

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

  /* see superclass */
  @SuppressWarnings("unused")
  @Override
  public ValidationResult validateAction(MolecularActionAlgorithm action) {
    ValidationResult result = new ValidationResultJpa();

    // Only run this check on merge and move actions
    if (!(action instanceof MergeMolecularAction || action instanceof MoveMolecularAction)){
      return result;
    }
    
    final Project project = action.getProject();
    final ContentService service = (AbstractMolecularAction) action;
    final Concept source = (action instanceof MergeMolecularAction
        ? action.getConcept2() : action.getConcept());
    final Concept target = (action instanceof MergeMolecularAction
        ? action.getConcept() : action.getConcept2());
    final List<Atom> source_atoms = (action instanceof MoveMolecularAction
        ? ((MoveMolecularAction)action).getMoveAtoms() : source.getAtoms());

    //
    // Obtain target atoms
    //
    List<Atom> target_atoms = target.getAtoms();

    //
    // Find publishable atom from source concept
    // having different last release cui from publishable
    // target concept atom.
    //
    for (Atom sourceAtom : source_atoms) {
      if (sourceAtom.isPublishable() && sourceAtom.getConceptTerminologyIds()
          .get(source.getTerminology()) != null) {
        for (Atom targetAtom : target_atoms) {
          if (targetAtom.isPublishable()
              && targetAtom.getConceptTerminologyIds()
                  .get(source.getTerminology()) != null
              && !targetAtom.getConceptTerminologyIds()
                  .get(source.getTerminology())
                  .equals(sourceAtom.getConceptTerminologyIds()
                      .get(source.getTerminology()))) {
            result.getErrors().add(getName()
                + ": Publishable atom in source concept has different Concept Terminology Id than publishable atom in target concept.");
            return result;
          }
        }
      }
    }
    return result;
  }

  /* see superclass */
  @Override
  public String getName() {
    return this.getClass().getSimpleName();
  }

}

@@ -1263,16 +1263,24 @@
 arAction
+%0A       
  %7C%7C acti
@@ -1314,16 +1314,17 @@
 Action))
+ 
 %7B%0A      
@@ -1344,20 +1344,16 @@
 ;%0A    %7D%0A
-    
 %0A    fin
@@ -1730,26 +1730,25 @@
 Atom%3E source
-_a
+A
 toms = (acti
@@ -1813,16 +1813,17 @@
 rAction)
+ 
 action).
@@ -1905,16 +1905,22 @@
  //%0A    
+final 
 List%3CAto
@@ -1924,26 +1924,25 @@
 Atom%3E target
-_a
+A
 toms = targe
@@ -2106,28 +2106,110 @@
     //%0A    f
-or (
+inal String projectTerminology = action.getProject().getTerminology();%0A    for (final 
 Atom sourceA
@@ -2220,18 +2220,17 @@
 : source
-_a
+A
 toms) %7B%0A
@@ -2238,16 +2238,17 @@
      if 
+(
 (sourceA
@@ -2266,16 +2266,100 @@
 shable()
+%0A          %7C%7C sourceAtom.getTerminology().equals(source.getTerminology()))%0A         
  && sour
@@ -2398,38 +2398,39 @@
 )%0A          
+    
 .get(
-source.ge
+projec
 tTerminology
@@ -2421,34 +2421,32 @@
 ojectTerminology
-()
 ) != null) %7B%0A   
@@ -2455,16 +2455,22 @@
    for (
+final 
 Atom tar
@@ -2489,10 +2489,9 @@
 rget
-_a
+A
 toms
@@ -2507,16 +2507,17 @@
      if 
+(
 (targetA
@@ -2528,32 +2528,110 @@
 isPublishable()%0A
+              %7C%7C targetAtom.getTerminology().equals(target.getTerminology()))%0A
               &&
@@ -2688,33 +2688,30 @@
        .get(
-source.ge
+projec
 tTerminology
@@ -2710,18 +2710,16 @@
 minology
-()
 ) != nul
@@ -2779,41 +2779,19 @@
 ds()
-%0A                  .get(source.ge
+.get(projec
 tTer
@@ -2798,18 +2798,16 @@
 minology
-()
 )%0A      
@@ -2891,25 +2891,22 @@
    .get(
-source.ge
+projec
 tTermino
@@ -2909,18 +2909,16 @@
 minology
-()
 ))) %7B%0A  
@@ -2949,22 +2949,8 @@
 rs()
-.add(getName()
 %0A   
@@ -2966,124 +2966,56 @@
     
-+ %22: Publishable atom in source concept has different Concept Terminology Id than publishable atom in target concept
+.add(getName() + %22: different last published cui
 .%22);

allow unpublishable project atoms to participate in MGV_A4