/*******************************************************************************
 * Copyright 2016 Centre for Development of Advanced Computing(C-DAC), Pune
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package in.cdac.medinfo.csnotk.csnolib.test;

import static org.junit.Assert.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import in.cdac.medinfo.csnotk.csnolib.agents.SNOMEDAgent;
import in.cdac.medinfo.csnotk.csnolib.icdmap.ICDMapAgent;
import in.cdac.medinfo.csnotk.csnolib.icdmap.MapResult;
import in.cdac.medinfo.csnotk.csnolib.icdmap.Record;
//Logs
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import in.cdac.medinfo.csnotk.csnolib.util.LoggerUtility;

import org.junit.Test;

/**
 * TestICDMapAgentJUnit class contains the test cases related to SNOMED CT to ICD-10 map.
 *
 */
public class TestICDMapAgentJUnit {

	static{
		SNOMEDAgent agent = new SNOMEDAgent();
		ICDMapAgent mapAgent = new ICDMapAgent();
		agent.init();
        Logger logger = LogManager.getLogger(TestICDMapAgentJUnit.class);
		logger.info(LoggerUtility.CONSOLE, "Do you want to create SNOMED CT to ICD map database (y/n)");
		BufferedReader serviceInput = new BufferedReader(
				new InputStreamReader(System.in));
		try {
			String dbOverride = serviceInput.readLine();
			if(dbOverride.equalsIgnoreCase("y"))
			{
				logger.info(LoggerUtility.CONSOLE, "Please Enter SNOMED CT Release file path till Snapshot");
				String snomedDirPath=serviceInput.readLine();
				mapAgent.createICDMapdb(snomedDirPath, true);
			}
		} catch (IOException e1) {
			//Log the Exception
			logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e1));
		}
	}


	/**
	 * test case for one SNOMED CT mapped to one ICD-10
	 */
	@Test
	public void testOneToOneMap() {
		ICDMapAgent agent = new ICDMapAgent();
		Record record = new Record();
		MapResult mapResult;

		//82272006 | Common cold (disorder)
		Long conceptId = (long) 82272006;
		record.setPrimarySCTID(conceptId);

		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//MAP_FOUND
		assertNotNull(mapResult.getMapStatus());
		assertEquals("MAP_FOUND", mapResult.getMapStatus());
		//only one group
		assertNotNull(mapResult.getMapGroup());
	}

	/**
	 * test case for one SNOMED CT mapped to many ICD-10 code
	 */
	@Test
	public void testOneToManyMap() {
		ICDMapAgent agent = new ICDMapAgent();
		Record record = new Record();
		MapResult mapResult;

		//60684003 | Synovitis acne pustulosis hyperostosis osteomyelitis syndrome (disorder)
		Long conceptId = (long) 60684003;
		record.setPrimarySCTID(conceptId);

		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//INDETERMINATE_MAP
		assertNotNull(mapResult.getMapStatus());
		assertEquals("INDETERMINATE_MAP", mapResult.getMapStatus());
		//multiple group or rules
		assertNotNull(mapResult.getMapGroup());
	}

	/**
	 * test case for one SNOMED CT mapped to none ICD-10 code
	 */
	@Test
	public void testOneToNoneMap() {
		ICDMapAgent agent = new ICDMapAgent();
		Record record = new Record();
		MapResult mapResult;

		//39266006 | Abnormal cell (cell)
		Long conceptId = (long) 39266006;
		record.setPrimarySCTID(conceptId);

		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//NO_MAP_FOUND
		assertNotNull(mapResult.getMapStatus());
		assertEquals("NO_MAP_FOUND", mapResult.getMapStatus());
		//No mapping group or rule
		assertNotNull(mapResult.getMapGroup());
	}

	/**
	 * test case for mapping SNOMED CT to ICD-10 code using provided gender
	 */
	@Test
	public void testGenderBasedMap() {
		ICDMapAgent agent = new ICDMapAgent();
		Record record = new Record();
		MapResult mapResult;

		//205705003 | Additional sex chromosome (disorder)
		Long conceptId = (long) 205705003;
		record.setPrimarySCTID(conceptId);

		//test for gender as male
		record.setGender("male");
		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//MAP_FOUND
		assertNotNull(mapResult.getMapStatus());
		assertEquals("MAP_FOUND", mapResult.getMapStatus());
		assertNotNull(mapResult.getMapGroup());

		//test for gender as female
		record.setGender("female");
		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//MAP_FOUND
		assertNotNull(mapResult.getMapStatus());
		assertEquals("MAP_FOUND", mapResult.getMapStatus());
		assertNotNull(mapResult.getMapGroup());

		//test for not provided gender
		record.setGender("");
		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//NO_MAP_FOUND
		assertNotNull(mapResult.getMapStatus());
		assertEquals("NO_MAP_FOUND", mapResult.getMapStatus());
		assertNotNull(mapResult.getMapGroup());
	}

	/**
	 * test case for mapping SNOMED CT to ICD-10 code using provided secondary diagnosis id
	 */
	@Test
	public void testUseSecondaryMap() {
		ICDMapAgent agent = new ICDMapAgent();
		Record record = new Record();
		MapResult mapResult;

		//205705003 | Additional sex chromosome (disorder)
		Long conceptId = (long) 205705003;
		record.setPrimarySCTID(conceptId);
		record.setSecondarySCTID("248153007");

		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//MAP_FOUND
		assertNotNull(mapResult.getMapStatus());
		assertEquals("MAP_FOUND", mapResult.getMapStatus());
		assertNotNull(mapResult.getMapGroup());

	}

	/**
	 * test case for mapping SNOMED CT to ICD-10 code using provided age
	 */
	@Test
	public void testAgeBasedMap() {
		ICDMapAgent agent = new ICDMapAgent();
		Record record = new Record();
		MapResult mapResult;

		//717934004 | Osteomalacia due to vitamin D deficiency (disorder)
		Long conceptId = (long) 717934004;
		record.setPrimarySCTID(conceptId);

		//test as birth date before eighteen years from current diagnosis date
		String birthdate = "10-03-2010";
		DateFormat df = new SimpleDateFormat("MM-dd-yyyy");
		Date birthDate = null;
		try {
			birthDate = df.parse(birthdate);
		} catch (ParseException e) {
			Logger logger = LogManager.getLogger(TestICDMapAgentJUnit.class);
			logger.error(LoggerUtility.CONSOLE, LoggerUtility.createErrorMessage(e));
		}
		record.setBirthDate(birthDate);
		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//INDETERMINATE_MAP
		assertNotNull(mapResult.getMapStatus());
		assertEquals("MAP_FOUND", mapResult.getMapStatus());
		assertNotNull(mapResult.getMapGroup());

		//test as birth date after sixty five years from current diagnosis date
		birthdate = "15-08-1948";
		try {
			birthDate = df.parse(birthdate);
		} catch (ParseException e) {
			Logger logger = LogManager.getLogger(TestICDMapAgentJUnit.class);
			logger.error(LoggerUtility.CONSOLE, LoggerUtility.createErrorMessage(e));
		}
		record.setBirthDate(birthDate);
		mapResult = agent.map(record);
		assertNotNull(mapResult);
		//INDETERMINATE_MAP
		assertNotNull(mapResult.getMapStatus());
		assertEquals("MAP_FOUND", mapResult.getMapStatus());
		assertNotNull(mapResult.getMapGroup());

	}

}
