package gov.va.vinci.dart.db.mock;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import gov.va.vinci.dart.common.exception.ObjectNotFoundException;
import gov.va.vinci.dart.biz.DataSource;
import gov.va.vinci.dart.biz.DocumentTemplate;
import gov.va.vinci.dart.db.DataSourceDAO;

public class DataSourceDAOMock implements DataSourceDAO {

	private static final HashMap<Integer,DataSource> IDHash = new HashMap<Integer,DataSource>();
	private static final HashMap<Integer,List<DataSource>> DTHash = new HashMap<Integer,List<DataSource>>();
	private static final HashMap<Integer,List<Integer>> DisabledHash = new HashMap<Integer,List<Integer>>();
	private static final HashMap<Integer,HashMap<Integer,List<DataSource>>> HeaderHash = new HashMap<Integer,HashMap<Integer,List<DataSource>>>();	//requestType, header, data sources
	
	private static boolean initialized = false;

	@Override
	public DataSource findById(int dataSourceId) throws ObjectNotFoundException {
		initializeDataSourceHashes();

		DataSource result = IDHash.get(dataSourceId);
		
		if (result == null) {
			throw new ObjectNotFoundException();
		}
		
		return result;
	}

	@Override
	public List<DataSource> listAll() {
		List<DataSource> result = new ArrayList<DataSource>();
		
		initializeDataSourceHashes();
		
		for (Integer id: IDHash.keySet()) {
			result.add(IDHash.get(id));
		}

		return result;
	}

	@Override
	public List<DataSource> findByDocumentTemplateId(int documentTemplateId) {
		initializeDataSourceHashes();
		
		List<DataSource> result = DTHash.get(documentTemplateId);
		if (result == null) {
			return new ArrayList<DataSource>();
		}
		
		return result;
	}
	
	@Override
	public List<Integer> findDisabledIdByRequestType(final int requestTypeId) {
		initializeDataSourceHashes();
		
		List<Integer> result = DisabledHash.get(requestTypeId);
		if (result == null) {
			return new ArrayList<Integer>();
		}
		
		return result;
	}
	
	@Override
	public List<DataSource> findByHeaderIdAndRequestType(final int dataSourceHeaderId, final int requestTypeId) {
		initializeDataSourceHashes();
		
		HashMap<Integer,List<DataSource>> dsMap = HeaderHash.get(requestTypeId);
		if( dsMap != null ) {

			List<DataSource> dsList = dsMap.get(dataSourceHeaderId);
			if (dsList == null) {
				return new ArrayList<DataSource>();
			}
		}
		
		return new ArrayList<DataSource>();
	}
	
	
	private void initializeDataSourceHashes() {
		if (initialized == true) {
			return;
		}
		
		try {
			initializeDataSourceHashes0();
			initializeDisabledDataSources1();
			initializeDataSourcesHeader1();
			
			initialized = true;			
		}
		catch (ObjectNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private void addDocumentTemplates(final DataSource ds, final int[] tids) throws ObjectNotFoundException {
	
		for (int tid : tids) {
			ds.getDocumentTemplates().add(DocumentTemplate.findById(tid));
			
			List<DataSource> dsList = DTHash.get(tid);
			
			if (dsList == null) {
				dsList = new ArrayList<DataSource>();
				DTHash.put(tid, dsList);
			}
			
			if (dsList.contains(ds) == false) {
				dsList.add(ds);
			}
		}
	}
	
	private void createDataSource(final int id, final String name, final String description, final String domain, final String evaluator, final int[] templates) throws ObjectNotFoundException {
		DataSource ds = new DataSource();
		ds.setId(id);
		ds.setName(name);
		ds.setDescription(description);
		ds.setDomainName(domain);
		ds.setInfoSite("");
		ds.setEvaluator(evaluator);
		ds.setDocumentTemplates(new HashSet<DocumentTemplate>());
		addDocumentTemplates(ds, templates);
		IDHash.put(ds.getId(), ds);
	}
	
	private void initializeDataSourceHashes0() throws ObjectNotFoundException {

		createDataSource(1, 
				"CDW", 
				"CDW (Extract - includes DSS NDE and Medical SAS)",
				"CDW", 
				"gov.va.vinci.dart.rule.CDWDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,19,21,23,24,26,27});
		
		createDataSource(2, 
				"DSS NDE", 
				"DSS NDE", 
				"DSS", 
				"gov.va.vinci.dart.rule.DSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,21,23,24,26,27});
		
		createDataSource(3, 
				"Vital Status (Real SSN)", 
				"Vital Status Crosswalk file with Real SSN", 
				"Vital Status",
				"gov.va.vinci.dart.rule.CDWDSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18});
		
		createDataSource(4, 
				"Med SAS Access (Real SSN)", 
				"Medical SAS Data Sets with Real SSNs (Mainframe...", 
				"Med SAS",
				"gov.va.vinci.dart.rule.MedSASDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,21,24,26,27});
		
		createDataSource(6, 
				"Vital Status (Scrambled SSN)", 
				"Vital Status File with Scrambled SSNs (SQL Server and SAS)", 
				"Vital Status", 
				"gov.va.vinci.dart.rule.VitalStatusScrambledDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,13,16,18,26,27});
		
		createDataSource(7, 
				"BIRLS Death File", 
				"BIRLS Death File (Mainframe Access)", 
				"BIRLS", 
				"gov.va.vinci.dart.rule.BIRLSDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,21,23,24,26,27});
		
		createDataSource(8, 
				"DSS Web Reports", 
				"DSS Web Reports", 
				"DSS", 
				"gov.va.vinci.dart.rule.BIRLSDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,21,23,24,26,27});
		
		createDataSource(9, 
				"OEF/OIF (Real SSN)", 
				"OEF/OIF Roster File with Real SSNs", 
				"OEF/OIF", 
				"gov.va.vinci.dart.rule.OEFOIFRealDocumentRuleEvaluator", 
				new int[]{9,10,21,23,24,25,27});
		
		createDataSource(10, 
				"OEF/OIF (Scrambled SSN)", 
				"OEF/OIF Roster File with Scrambled SSNs", 
				"OEF/OIF", 
				"gov.va.vinci.dart.rule.OEFOIFRealDocumentRuleEvaluator", 
				new int[]{9,10,21,24,25,27});
		
		createDataSource(11, 
				"Vital Status (Mainframe - Real SSN)", 
				"Vital Status Crosswalk File with Real SSNs (Mainframe Access)", 
				"Vital Status", 
				"gov.va.vinci.dart.rule.BIRLSDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,21,23,24,26,27});
		
		createDataSource(12, 
				"Vital Status (Mainframe - Scrambled SSN)", 
				"Vital Status with Scrambled SSN (Mainframe Access)", 
				"Vital Status", 
				"gov.va.vinci.dart.rule.VitalStatusMainframeScrambledDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,13,16,18,26,27});
		
		createDataSource(13, 
				"VSSC Web Reports", 
				"VSSC Web Reports", 
				"VSSC", 
				"gov.va.vinci.dart.rule.BIRLSDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,21,23,24,26,27});
		
		createDataSource(1001, 
				"CAPRI", 
				"CAPRI", 
				"VistA", 
				"gov.va.vinci.dart.rule.CapriDocumentRuleEvaluator", 
				new int[]{4,5,7,9,13,18,43});
		
		createDataSource(1002, 
				"VistAWeb", 
				"VistAWeb", 
				"VistA", 
				"gov.va.vinci.dart.rule.CapriDocumentRuleEvaluator", 
				new int[]{});  // TODO- are you sure this data source has no associated document templates?
		
		createDataSource(1003, 
				"Basic Read Access (Includes Production and Raw Domains)", 
				"Basic Read Access", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1004, 
				"Privileged Read Access (Provides access to SPatient Schema)", 
				"Privileged Read Access", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1005, 
				"SStaff (Provides access to SStaff Schema includes Staff Real SSN)", 
				"SStaff Schema", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1006, 
				"CDW DSS NDE", 
				"CDW DSS NDE", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1007, 
				"Vital Status", 
				"Vital Status", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1008, 
				"BIRLS Real SSN", 
				"BIRLS Real SSN", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1009, 
				"DSS NDE SAS (legacy files)", 
				"DSS NDE SAS (legacy files)", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1010, 
				"MedSAS Files including VetsNet Files", 
				"MedSAS Files including VetsNet Files", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1011, 
				"Vital Status Files with Scrambled SSN", 
				"Vital Status Files with Scrambled SSN", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1012, 
				"Vital Status File Real SSN Crosswalk File", 
				"Vital Status File Real SSN Crosswalk File", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1013, 
				"BIRLS Real SSN (110JJ02)", 
				"BIRLS Real SSN (Mainframe Access)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1014, 
				"MedSAS Files including VetsNet Files National Level Real SSN (1100TT01)", 
				"MedSAS Files National Level Real SSN (Mainframe Access)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1015, 
				"MedSAS Files VISN Level Real SSN (1100TT05)", 
				"MedSAS Files VISN Level Real SSN (Mainframe Access)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1016, 
				"Vital Status Files with Scrambled SSN (110NN06)", 
				"Vital Status File with Scrambled SSN (Mainframe Access)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1017, 
				"Vital Status File Real SSN Crosswalk File (110TT20)", 
				"Vital Status File Real SSN Crosswalk File (Mainframe Access)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1018, 
				"DSS Web Reports", 
				"DSS Web Reports", 
				"Other Data", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1019, 
				"OEF/OIF Roster File", 
				"OEF/OIF Roster File", 
				"Other Data", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1020, 
				"VSSC Web Reports", 
				"VSSC Web Reports", 
				"Other Data", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1021, 
				"Use of the SAS Grid", 
				"Use of the SAS Grid", 
				"Data Access Systems and Tools", 
				"gov.va.vinci.dart.rule.OperationalDocumentRuleEvaluator", 
				new int[]{45});
		
		createDataSource(1022, 
				"CDW Production Domains (Must complete CDW Production Domain Checklist)", 
				"CDW Production Domains", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.CDWDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,19});
		
		createDataSource(1023, 
				"CDW Raw Domains (Must complete CDW Raw Domain Checklist)", 
				"CDW Raw Domains", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.CDWDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,19});
		
		createDataSource(1024, 
				"CDW DSS NDE", 
				"CDW DSS NDE", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.CDWDSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18});
		
		createDataSource(1025, 
				"TIU Text Notes (Requires Real SSN Approval)", 
				"TIU Text Notes", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.CDWDSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18});
		
		createDataSource(1026, 
				"Vital Status", 
				"Vital Status", 
				"CDW; SQL Format", 
				"gov.va.vinci.dart.rule.VitalStatusSQLFormatRealDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,16,18});
		
		createDataSource(1027, 
				"BIRLS", 
				"BIRLS", 
				"CDW; SAS", 
				"gov.va.vinci.dart.rule.CDWDSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18});
		
		createDataSource(1028, 
				"DSS NDE (legacy)", 
				"DSS NDE (legacy)", 
				"CDW; SAS", 
				"gov.va.vinci.dart.rule.CDWDSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18});
		
		createDataSource(1029, 
				"MedSAS Files including VetsNet Files", 
				"MedSAS Files including VetsNet Files", 
				"CDW; SAS", 
				"gov.va.vinci.dart.rule.CDWDSSNDEDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18});
		
		createDataSource(1030, 
				"MedSAS including VetsNet Files for National Level Real SSN (1100TT01)", 
				"MedSAS including VetsNet Files for National Level Real SSN (1100TT01)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.BIRLSDocumentRuleEvaluator", 
				new int[]{4,5,7,10,12,13,18,21,23,24,26,27});
		
		createDataSource(1031, 
				"MedSAS Files for VISN Level Real SSN (1100TT05)", 
				"MedSAS Files for VISN Level Real SSN (1100TT05)", 
				"Mainframe", 
				"gov.va.vinci.dart.rule.BIRLSDocumentRuleEvaluator", 
				new int[]{4,5,7,10,12,13,18,21,23,24,26,27});
		
		createDataSource(1032, 
				"Legacy Data Warehouses (i.e. VISN 21)", 
				"Legacy Data Warehouses", 
				"Other", 
				"gov.va.vinci.dart.rule.CDWDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,19});
		
		createDataSource(1033, 
				"OEF/OIF Roster File", 
				"OEF/OIF Roster File", 
				"Other", 
				"gov.va.vinci.dart.rule.OEFOIFRealDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,13,18,21,23,24,25,42,46});
		
		createDataSource(1034, 
				"Surgery Quality Data Users Group (SQDUG)", 
				"Surgery Quality Data Users Group (SQDUG)", 
				"Other", 
				"gov.va.vinci.dart.rule.CDWDocumentRuleEvaluator", 
				new int[]{4,5,7,9,10,12,13,18,19});
		
		createDataSource(1035, 
				"SAS Grid", 
				"SAS Grid", 
				"Data Access Systems", 
				"gov.va.vinci.dart.rule.SASGridDocumentRuleEvaluator", 
				new int[]{});	//7,13});	//new int[]{4,5,7,9,10,12,13,18,19});

	}
	
	private void initializeDisabledDataSources1() {
		
		int[] disabledDataSourceIDs = {1027, 1028, 6, 3};

		List<Integer> dsList = new ArrayList<Integer>();		
		
		for( int dsId : disabledDataSourceIDs ) {
			dsList.add(dsId);
		}//end for
		
		DisabledHash.put(2, dsList);
	}	

	private HashMap<Integer, List<DataSource>> populateDSMap(int headerId, int[] dataSourceIDs) {

		HashMap<Integer, List<DataSource>> dsMap = new HashMap<Integer, List<DataSource>>();
		List<DataSource> dsList = new ArrayList<DataSource>();
		
		for( int dsId : dataSourceIDs ) {

			DataSource ds = null;
			try {
				
				ds = findById(dsId);
				dsList.add(ds);

			} catch (ObjectNotFoundException e) {
				e.printStackTrace();
			}

		}//end for
		
		dsMap.put(headerId, dsList);
		
		return dsMap;
	}
	
	private void initializeDataSourcesHeader1() {
		
		HashMap<Integer, List<DataSource>> dsMap = new HashMap<Integer, List<DataSource>>();
		
		dsMap.putAll( populateDSMap( 2, new int[]{1022, 1023, 1024, 1029, 1025, 1026} ) );
	
		dsMap.putAll( populateDSMap( 3, new int[]{1027, 1028, 6, 3} ) );
		
		dsMap.putAll( populateDSMap( 4, new int[]{7, 1030, 1031, 12, 11} ) );

		dsMap.putAll( populateDSMap( 5, new int[]{1001, 8, 1036, 1032, 1033, 1034, 13} ) );

		dsMap.putAll( populateDSMap( 6, new int[]{1035} ) );
		
		HeaderHash.put(2, dsMap);	//requestType, header, data sources
	}	
	
}
