package org.slc.sli.ingestion.referenceresolution;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.ws.Holder;

import junit.framework.Assert;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.xml.sax.SAXException;

import org.slc.sli.ingestion.IngestionTest;

/**
 *
 * @author tke
 *
 */
public class FreeMarkerExtendedReferenceResolverTest {
    FreeMarkerExtendedReferenceResolver referenceFactory = new FreeMarkerExtendedReferenceResolver();

    private void test(File content, File expected, String xpath) throws IOException {
        File result = null;
        try {
            result = referenceFactory.resolve(xpath, content);

            Assert.assertNotNull(result);

            String expectedXML = readFromFile(expected);
            String actualXML = readFromFile(result);

            expectedXML = expectedXML.replaceAll("\\n|\\r", "");
            expectedXML = expectedXML.replaceAll("\\s+", "");
            actualXML = actualXML.replaceAll("\\n|\\r", "");
            actualXML = actualXML.replaceAll("\\s+", "");

            Assert.assertEquals(expectedXML, actualXML);
        } finally {
            if (result != null) {
                result.delete();
            }
        }
    }

    private String readFromFile(File file) throws IOException {
        FileReader reader = null;

        try {
            reader = new FileReader(file);

            List<String> lines = IOUtils.readLines(reader);

            return StringUtils.join(lines, '\n');
        } finally {
            IOUtils.closeQuietly(reader);
        }
    }

    @Test
    public void testResolution() throws IOException, SAXException {
        final File input = IngestionTest.getFile("idRefResolutionData/InterchangeStudentParent/StudentReference_input.xml");
        final File expected = IngestionTest.getFile("idRefResolutionData/InterchangeStudentParent/StudentReference_output.xml");

        Map<String, String> config = new HashMap<String, String>();
        config.put("/InterchangeStudentParent/StudentParentAssociation/StudentReference", "idRefResolution/InterchangeStudentParent/StudentParentAssociation/StudentReference.ftl");

        referenceFactory.setIdRefConfigs(config);

        test(input, expected, "/InterchangeStudentParent/StudentParentAssociation/StudentReference");

        final Holder<Boolean> exceptionThrown = new Holder<Boolean>(Boolean.FALSE);

        Runnable run = new Runnable() {
            @Override
            public void run() {
                try {
                    test(input, expected, "/InterchangeStudentParent/StudentParentAssociation/StudentReference");
                } catch (Throwable t) {
                    exceptionThrown.value = Boolean.TRUE;
                    throw new RuntimeException(t);
                }
            }
        };

        Thread th1 = new Thread(run, "Thread1");

        Thread th2 = new Thread(run, "Thread2");

        th1.start();
        th2.start();

        try {
            th1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
            Assert.fail();
        }

        try {
            th2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
            Assert.fail();
        }

        Assert.assertFalse(exceptionThrown.value);
    }

    @Test
    public void testBadConfiguration() {
        Map<String, String> config = new HashMap<String, String>();
        referenceFactory.setIdRefConfigs(config);

        config.put("/InterchangeStudentAssessment/StudentAssessment/AssessmentReference", "idRefResolution/InterchangeAssessmentMetadata/Assessment/AssessmentFamilyReference.ftl");

        Assert.assertNull(referenceFactory.resolve("/InterchangeStudentAssessment/StudentAssessment/AssessmentReference2", null));
    }

}

@@ -647,20 +647,22 @@
 id test(
-File
+String
  content
@@ -721,20 +721,22 @@
         
-File
+String
  result 
@@ -743,34 +743,16 @@
 = null;%0A
-        try %7B%0A    
         
@@ -803,36 +803,32 @@
 tent);%0A%0A        
-    
 Assert.assertNot
@@ -846,28 +846,24 @@
 );%0A%0A        
-  
-  
 String expec
@@ -899,28 +899,24 @@
 d);%0A        
-    
 String actua
@@ -926,35 +926,17 @@
 L = 
-readFromFile(
 result
-)
 ;%0A%0A
-    
     
@@ -996,28 +996,24 @@
 %22);%0A        
-    
 expectedXML 
@@ -1042,36 +1042,32 @@
 ll(%22%5C%5Cs+%22, %22%22);%0A
-    
         actualXM
@@ -1111,28 +1111,24 @@
 %22);%0A        
-    
 actualXML = 
@@ -1158,28 +1158,24 @@
 %5Cs+%22, %22%22);%0A%0A
-    
         Asse
@@ -1219,119 +1219,8 @@
 L);%0A
-        %7D finally %7B%0A            if (result != null) %7B%0A                result.delete();%0A            %7D%0A        %7D%0A
     
@@ -1679,32 +1679,49 @@
  = IngestionTest
+%0A                
 .getFile(%22idRefR
@@ -1832,16 +1832,33 @@
 tionTest
+%0A                
 .getFile
@@ -2085,32 +2085,48 @@
 udentReference%22,
+%0A               
  %22idRefResolutio
@@ -2258,37 +2258,51 @@
 ;%0A%0A        test(
+readFromFile(
 input
+)
 , expected, %22/In
@@ -2596,21 +2596,35 @@
    test(
+readFromFile(
 input
+)
 , expect
@@ -2618,32 +2618,60 @@
 nput), expected,
+%0A                           
  %22/InterchangeSt
@@ -3684,16 +3684,32 @@
 erence%22,
+%0A               
  %22idRefR
@@ -3844,16 +3844,33 @@
 resolve(
+%0A                
 %22/Interc

fix broken unit test