package org.gcube.application.geoportal;

import java.io.File;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;

import org.gcube.application.geoportal.model.MOSI;
import org.gcube.application.geoportal.model.MOSI.CD_Type;
import org.gcube.application.geoportal.model.MOSI.CD_Type.ACC_Type;
import org.gcube.application.geoportal.model.MOSI.CM_Type;
import org.gcube.application.geoportal.model.MOSI.DA_Type;
import org.gcube.application.geoportal.model.MOSI.DO_Type;
import org.gcube.application.geoportal.model.MOSI.DT_Type;
import org.gcube.application.geoportal.model.MOSI.Extent_Type;
import org.gcube.application.geoportal.model.MOSI.GE_Type;
import org.gcube.application.geoportal.model.MOSI.GE_Type.GEC_Type;
import org.gcube.application.geoportal.model.MOSI.IP_Type;
import org.gcube.application.geoportal.model.MOSI.IP_Type.IAP_Type;
import org.gcube.application.geoportal.model.MOSI.LC_Type;
import org.gcube.application.geoportal.model.MOSI.MT_Type;
import org.gcube.application.geoportal.model.MOSI.MT_Type.MTA_Type;
import org.gcube.application.geoportal.model.MOSI.OG_Type;
import org.gcube.application.geoportal.model.MOSI.RE_Type;
import org.gcube.application.geoportal.model.MOSI.RE_Type.FOI_Type;
import org.gcube.application.geoportal.model.MOSI.RE_Type.MTP_Type;
import org.gcube.application.geoportal.model.MOSI.TU_Type;
import org.gcube.application.geoportal.model.MOSI.TU_Type.NVC_Type;
import org.gcube.application.geoportal.model.MOSI.TU_Type.STU_Type;
import org.gcube.application.geoportal.model.db.DBInteractionException;
import org.gcube.application.geoportal.model.db.PostgisTable;
import org.gcube.application.geoportal.model.fault.DataParsingException;
import org.gcube.application.geoportal.model.fault.GeoPackageInteractionException;
import org.gcube.application.geoportal.storage.PostgisDBManagerI;
import org.gcube.application.geoportal.model.MOSI.VR_Type;
import org.gcube.application.geoportal.utils.Files;
import org.gcube.application.geoportal.utils.GpkgUtils;
import org.junit.BeforeClass;
import org.junit.Test;

import mil.nga.geopackage.GeoPackage;

public class GeopackageTests {

	static PostgisTableFactory factory;
	static GeoPackage gpkg;
	
	@BeforeClass
	public static void init() {
		factory = new PostgisTableFactory(new PostgisMockup());
		
		File gpkgFile = Files.getFileFromResources("gpkg/ArcheoPrevTemplateItalia.gpkg");
		gpkg=GpkgUtils.open(gpkgFile);
		
		
		
	}
	
	@Test
	public void readMOSI() throws GeoPackageInteractionException, SQLException, DBInteractionException, DataParsingException {
	
		factory.fromGPKGFeatureTable(gpkg, "MOSI_multipolygon");
		factory.fromGPKGFeatureTable(gpkg, "MOSI_multilinea");
		factory.fromGPKGFeatureTable(gpkg, "MOSI_point");
		
	}
	
	
	@Test(expected = GeoPackageInteractionException.class) 
	public void failMissingGeom() throws SQLException, GeoPackageInteractionException, DBInteractionException, DataParsingException {
		factory.fromGPKGFeatureTable(gpkg, "MOSI_SW");
	}
	
	
	@Test
	public void loadMosi() {
		
//		factory.fromGPKGFeatureTable(gpkg, featureTableName)
		
		
	}
	
	public static MOSI fromTable(PostgisDBManagerI db, PostgisTable mosiTable) throws SQLException {
		ResultSet rs= db.queryAll(mosiTable);
		CD_Type CD=new CD_Type();
		HashSet<ACC_Type> ACCs=new HashSet<>();
		
		OG_Type OG=new OG_Type();
		HashSet<String> OGNs=new HashSet<>();
		
		LC_Type LC=new LC_Type();
		HashSet<String> PVLs=new HashSet<>();
		
		DT_Type DT=new DT_Type();		
		DA_Type DA=new DA_Type();
		HashSet<String> OGMs=new HashSet<>();
		
		GE_Type GE=new GE_Type();
		HashSet<GEC_Type> GECs=new HashSet<>();
		
		TU_Type TU=new TU_Type();
		HashSet<NVC_Type> NVCs=new HashSet<>();
		HashSet<STU_Type> STUs=new HashSet<>();
		
		RE_Type RE=new RE_Type();
		HashSet<MTP_Type> MTPs=new HashSet<>();
		HashSet<FOI_Type> FOIs=new HashSet<>();
		
		IP_Type IP=new IP_Type();
		HashSet<IAP_Type> IAPs=new HashSet<>();
		
		
		MT_Type MT=new MT_Type();
		HashSet<MTA_Type> MTAs=new HashSet<>();
		
		VR_Type VR=new VR_Type();
		DO_Type DO=new DO_Type();
		
		
		
		
		CM_Type CM=new CM_Type();
		Extent_Type extent=new Extent_Type();
		HashMap<String, String> singleValues=new HashMap<String, String>();
		
		
		ResultSetMetaData meta=rs.getMetaData();
		int colCount=meta.getColumnCount();
		String[] fields=new String[colCount];
		
		for(int i=0; i<meta.getColumnCount(); i++) {
			fields[i]=meta.getColumnName(i+1);
		}
		
		while(rs.next()) {

			//Set values into map if not null
			for(String field:fields) {
				String value=rs.getString(field);				
				if(value!=null)singleValues.putIfAbsent(field, value);
			}

			//Collect multiple values if not null
			if(rs.getString("acce")!=null)
				ACCs.add(new ACC_Type(rs.getString("acce"), rs.getString("accc"), rs.getString("accs")));
			
			if(rs.getString("ogn")!=null)
				OGNs.add(rs.getString("ogn"));
			
			if(rs.getString("pvl")!=null)
				PVLs.add(rs.getString("pvl"));
			
			if(rs.getString("ogm")!=null)
				OGMs.add(rs.getString("ogm"));
			
			if(rs.getString("gecx")!=null)
				GECs.add(new GEC_Type(rs.getString("gecx"), rs.getString("gecy")));
			
			if(rs.getString("nvct")!=null||rs.getString("nvcm")!=null||rs.getString("nvce")!=null||rs.getString("nvcp")!=null||rs.getString("nvcn")!=null)
				NVCs.add(new NVC_Type(rs.getString("nvct"),rs.getString("nvcm"),rs.getString("nvce"),rs.getString("nvcp"),rs.getString("nvcn")));
			
			if(rs.getString("stue")!=null||rs.getString("stut")!=null||rs.getString("stus")!=null) 
				STUs.add(new STU_Type(rs.getString("stue"),rs.getString("stut"),rs.getString("stus")));
			
			if(rs.getString("mtpc")!=null)
				MTPs.add(new MTP_Type(rs.getString("mtpc"),rs.getString("mtpz")));
			
			if(rs.getString("foit")!=null||rs.getString("foir")!=null||rs.getString("foia")!=null||rs.getString("foiq")!=null||rs.getString("foif")!=null||rs.getString("foio")!=null||rs.getString("foin")!=null)
				FOIs.add(new FOI_Type(rs.getString("foit"),rs.getString("foir"),rs.getString("foia"),rs.getString("foiq"),rs.getString("foif"),rs.getString("foio"),rs.getString("foin")));
			
			if(rs.getString("iapn")!=null)
				IAPs.add(new IAP_Type(rs.getString("iapn"), rs.getString("iapr"), rs.getString("iapi"), rs.getString("iaps")));
			
			if(rs.getString("mtap")!=null||rs.getString("mtam")!=null||rs.getString("mtax")!=null||rs.getString("mtar")!=null||rs.getString("mtas")!=null)
				MTAs.add(new MTA_Type(rs.getString("mtap"),rs.getString("mtam"),rs.getString("mtax"),rs.getString("mtar"),rs.getString("mtas")));
			
			
		}
		
		return new MOSI(CD,OG,LC,DT,DA,GE,TU,RE,IP,MT,VR,DO,CM,extent);
	}
}
