package ingestDataTest;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;

import org.hadatac.console.controllers.annotator.AutoAnnotator;
import org.hadatac.data.loader.AnnotationWorker;
import org.hadatac.entity.pojo.DataFile;
import org.hadatac.entity.pojo.Deployment;
import org.hadatac.entity.pojo.Instrument;
import org.hadatac.entity.pojo.InstrumentType;
import org.hadatac.entity.pojo.Measurement;
import org.hadatac.entity.pojo.Platform;
import org.hadatac.metadata.loader.URIUtils;
import org.hadatac.utils.ConfigProp;
import org.hadatac.utils.NameSpace;
import org.hadatac.utils.State;

public class LoadDPLTest extends StepTest{
	private static LoadDPLTest test = new LoadDPLTest();

	private final int PAGESIZE = 20;
	private final int OFFSET = 0;
	private final int PLATFORMSIZE = 2;
	private final String PLATFORMNAME1 = "Measurement from Instrument";
	private final String PLATFORMNAME2 = "Elicitation from Human";
	private final String PLATFORMTYPE1 = "Platform";
	private final String PLATFORMTYPE2 = "human";
	private final int DEPLOYMENTSIZE = 2;
	private final String DEPLOYMENTINS1 = "Generic Instrument";
	private final String DEPLOYMENTINS2 = "Generic Questionnaire";

	private LoadDPLTest() {}

	public static LoadDPLTest getTest()
	{
		return test;
	}

	@Override
	public void test() {
      if(true){
         System.out.println("This test was skipped because the required data files are missing.");
         return;
      }

      //delete all existing processed csv
		List<DataFile> dataFiles = DataFile.findByStatus(DataFile.PROCESSED);
		for (DataFile dataFile : dataFiles)
		{
			//equivalent to part of AutoAnnotator.deleteDataFile("/", id)
			File file = new File(dataFile.getAbsolutePath());

	        if (dataFile.getPureFileName().startsWith("DA-")) {
	            Measurement.deleteFromSolr(dataFile.getDatasetUri());
	            NameSpace.deleteTriplesByNamedGraph(URIUtils.replacePrefixEx(dataFile.getDataAcquisitionUri()));
	        } else {
	            try {
	                AutoAnnotator.deleteAddedTriples(file, dataFile);
	            } catch (Exception e) {
	                System.out.print("Can not delete triples ingested by " + dataFile.getFileName() + " ..");
	                file.delete();
	                dataFile.delete();

	                //return redirect(routes.AutoAnnotator.index(dir, "."));
	            }
	        }
	        file.delete();
	        dataFile.delete();
		}

		System.out.println("[Step 4] Deleted all existing processed csv file");

		//delete all unprocessed files
		dataFiles = DataFile.findByStatus(DataFile.UNPROCESSED);
		for(DataFile dataFile : dataFiles)
		{
			File file = new File(dataFile.getAbsolutePath());
			dataFile.delete();
			file.delete();
		}
		System.out.println("[Step 4] Deleted all existing unprocessed csv file");

		//delete all freezed files
		dataFiles = DataFile.findByStatus(DataFile.FREEZED);
		for(DataFile dataFile : dataFiles)
		{
			File file = new File(dataFile.getAbsolutePath());
			dataFile.delete();
			file.delete();
		}
		System.out.println("[Step 4] Deleted all existing freezed csv file");
      dataFiles.clear();

		//delete all working files
		dataFiles = DataFile.findByStatus(DataFile.WORKING);
		for(DataFile dataFile : dataFiles)
		{
			File file = new File(dataFile.getAbsolutePath());
			dataFile.delete();
			file.delete();
		}
		System.out.println("[Step 4] Deleted all existing working csv file");

      // Release Memory we need it
      dataFiles.clear();
      dataFiles = null;

		//put DPL into unprocessed_csv
		try {
			Files.copy(java.nio.file.Paths.get("test/src/DPL-CHEAR-v2.xlsx"), java.nio.file.Paths.get(ConfigProp.getPathUnproc()+"/DPL-CHEAR-v2.xlsx"), StandardCopyOption.REPLACE_EXISTING);
		} catch (IOException e) {
			fail("Fail to copy DPL from test/src to "+ConfigProp.getPathUnproc());
		}

		//process the DPL
		AnnotationWorker.scan();
		AnnotationWorker.autoAnnotate();

		System.out.println("[Step 4] Process DPL pass.");

		//check absence of DPL in unprocessed_csv
		File file = new File(ConfigProp.getPathUnproc()+"/DPL-CHEAR-v2.xlsx");
		assertTrue(ConfigProp.getPathUnproc()+"/DPL-CHEAR-v2.xlsx not deleted after loading DPL", !file.exists());

		//check existence of DPL in processed_csv
		file = new File(ConfigProp.getPathProc()+"/DPL-CHEAR-v2.xlsx");
		assertTrue("Fail to detect "+ConfigProp.getPathProc()+"/DPL-CHEAR-v2.xlsx after loading DPL", file.exists());

      // Release Memory we need it
      file = null;

		System.out.println("[Step 4] DPL process file check pass.");

		//check platforms
		List<Platform> platforms = Platform.findWithPages(PAGESIZE, OFFSET * PAGESIZE);
		assertTrue(String.format("Incorrect size of platforms after loading DPL. Should be %d, but was %d.", PLATFORMSIZE, platforms.size()), PLATFORMSIZE == platforms.size());

		assertTrue(String.format("Incorrect platforms[0] label after loading DPL. Should be %s, but was %s", PLATFORMNAME1, platforms.get(0).getLabel()), platforms.get(0).getLabel().equals(PLATFORMNAME1));
		assertTrue(String.format("Incorrect platforms[0] type after loading DPL. Should be %s, but was %s", PLATFORMTYPE1, platforms.get(0).getTypeLabel()), platforms.get(0).getTypeLabel().equals(PLATFORMTYPE1));
		assertTrue(String.format("Incorrect platforms[1] label after loading DPL. Should be %s, but was %s", PLATFORMNAME2, platforms.get(1).getLabel()), platforms.get(1).getLabel().equals(PLATFORMNAME2));
		assertTrue(String.format("Incorrect platforms[1] type after loading DPL. Should be %s, but was %s", PLATFORMTYPE2, platforms.get(1).getTypeLabel()), platforms.get(1).getTypeLabel().equals(PLATFORMTYPE2));

		System.out.println("[Step 4] DPL Platform check pass.");

      // Release Memory we need it
      platforms.clear();
      platforms = null;

		//check instruments
		//TODO: not fully implemented. Unable to know the correct result of instruments.
		/*List<Instrument> instruments = Instrument.find();
		System.out.println("Instruments Size: "+instruments.size());
		for(Instrument ins : instruments)
		{
			System.out.println("Instrument: Name: "+ins.getLabel() + " Type: "+ins.getTypeLabel());
		}
		List<InstrumentType> instrumentTypes = InstrumentType.find();
		for(InstrumentType insT : instrumentTypes)
		{
			System.out.println("Instrument Type: Name: "+insT.getLabel()+" SuperClass: "+insT.getSuperLabel());
		}
		System.out.println("[Step 4] DPL Instrument check pass.");*/

		//check deployments
		List<Deployment> deployments = Deployment.findWithPages(new State(State.ACTIVE), PAGESIZE, OFFSET * PAGESIZE);
		assertTrue(String.format("Incorrect size of deployments after loading DPL. Should be %d, but was %d.", DEPLOYMENTSIZE, deployments.size()), DEPLOYMENTSIZE == deployments.size());

		assertTrue(String.format("Incorrect deployments[0] platform label after loading DPL. Should be %s, but was %s", PLATFORMNAME1, deployments.get(0).getPlatform().getLabel()), deployments.get(0).getPlatform().getLabel().equals(PLATFORMNAME1));
		assertTrue(String.format("Incorrect deployments[0] instrument label after loading DPL. Should be %s, but was %s", DEPLOYMENTINS1, deployments.get(0).getInstrument().getLabel()), deployments.get(0).getInstrument().getLabel().equals(DEPLOYMENTINS1));
		assertTrue(String.format("Incorrect deployments[1] platform label after loading DPL. Should be %s, but was %s", PLATFORMNAME2, deployments.get(1).getPlatform().getLabel()), deployments.get(1).getPlatform().getLabel().equals(PLATFORMNAME2));
		// assertTrue(String.format("Incorrect deployments[1] instrument label after loading DPL. Should be %s, but was %s", DEPLOYMENTINS2, platforms.get(1).getTypeLabel()), deployments.get(1).getInstrument().getLabel().equals(DEPLOYMENTINS2));

		System.out.println("[Step 4] DPL Deployment check pass.");

		System.out.println("[Step 4] Load DPL Test Pass.");

      // Release Memory we need it
      deployments.clear();
      deployments = null;
	}

	@Override
	public void preMsg() {
		System.out.println("[Step 4] Executing loadDPLTest:");

	}

	@Override
	public int step() {
		return 4;
	}
}
