package testUnitaire.database.migration.etape1;

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

import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

import tool.iterator.Inside;
import database.dataset.Depot;
import database.dataset.Employe;
import database.dataset.Fermeture;
import database.dataset.Utilisateur;
import database.migration.SqlFactory;
import database.migration.etape1.depotEtFermeture.NormalisedDepotAndFermeture;
import database.migration.etape1.depotEtFermeture.ReadDepot;
import database.migration.etape1.depotEtFermeture.ReadFermeture;

public class testNormalisedDepotAndFermeture {

	private static java.sql.Connection connection;
	private static NormalisedDepotAndFermeture normalisedDepotAndFermeture;
	
	@BeforeClass
	public static void init() throws FileNotFoundException, SQLException, IOException{
		connection = SqlFactory.connect(SqlFactory.loadProperties("hotel_orford_import.xml"));
		normalisedDepotAndFermeture = normalisedDepotAndFermeture.from(ReadFermeture.from(connection), ReadDepot.from(connection));
	}

	@AfterClass
	public static void purge() throws SQLException{
		connection.close();
	}
	
	@Test
	public void testUnDepotManquant() throws SQLException {
		System.out.println("verification de tous les depots de la BD orginale");
		Statement stm = connection.createStatement();
		ResultSet rs = stm.executeQuery("SELECT ID,date FROM depots");
		
		while (rs.next()){
			int id = rs.getInt("ID");
			Date date = rs.getDate("date");
			boolean found = false;
			for (Depot depot : normalisedDepotAndFermeture.getDepots()){
				if (depot.getDepot_date().equals(date) && 
				    depot.getDepot_p_id()==id){
					found=true;
					break;
				}
			}
			assertTrue("ne trouve pas "+id +" "+date.toString(),found);
		}
		System.out.println("success");
	}
	
	@Test
	public void testUneFermetureManquante() throws SQLException {
		System.out.println("verification de toutes les fermetures de la BD orginale");
		Statement stm = connection.createStatement();
		ResultSet rs = stm.executeQuery("SELECT ID,date FROM fermeture");
		
		while (rs.next()){
			int id = rs.getInt("ID");
			Date date = rs.getDate("date");
			boolean found = false;
			for (Fermeture fermeture : normalisedDepotAndFermeture.getFermetures()){
				if (fermeture.getFermeture_jour().equals(date) && 
					fermeture.getfermeture_p_id()==id){
					found=true;
					break;
				}
			}
			assertTrue("ne trouve pas "+id +" "+date.toString(),found);
		}
		System.out.println("success");
	}
	
	/*employe et utilisateur ne peuvent être tester car ils sont générer*/
	
	@Test
	public void testDeDuplicationDeCleDepot(){
		for (Depot depot : normalisedDepotAndFermeture.getDepots()){
			for (Depot rest : normalisedDepotAndFermeture.getDepots())
				assertFalse("clé dépot dupliqué "+ depot.getDepot_p_id(),!depot.equals(rest) && depot.getDepot_p_id()==rest.getDepot_p_id());
					
		}
	}
	
	@Test
	public void testDeDuplicationDeCleFermeture(){
		for (Fermeture fermeture : normalisedDepotAndFermeture.getFermetures()){
			for (Fermeture rest : normalisedDepotAndFermeture.getFermetures())
				assertFalse("clé fermeture dupliqué "+ fermeture.getfermeture_p_id(),!fermeture.equals(rest) && fermeture.getfermeture_p_id()==rest.getfermeture_p_id());
					
		}
	}
	
	@Test
	public void testDeDuplicationDeCleEmploye(){
		for (Employe employe : normalisedDepotAndFermeture.getEmployes())
			for (Employe rest : normalisedDepotAndFermeture.getEmployes())
				assertFalse("clé employe dupliqué "+ employe.getemploye_p_id(), !employe.equals(rest) && employe.getemploye_p_id()==rest.getemploye_p_id());
	}
	
	@Test
	public void testDeDuplicationDeCleUtilisateur(){
		for (Utilisateur utilisateur : normalisedDepotAndFermeture.getUtilisateurs())
			for (Utilisateur rest : normalisedDepotAndFermeture.getUtilisateurs())
				assertFalse("clé utilisateur dupliqué "+ utilisateur.getutilisateur_p_id(), !utilisateur.equals(rest) && utilisateur.getutilisateur_p_id()==rest.getutilisateur_p_id());
	}
	
	@Test
	public void testDintegriteReferentielEntreFermetureEtDepot(){
		Inside<Depot,Fermeture> foundIn = new Inside<Depot,Fermeture>(){
			public boolean have(Iterable<Depot> lst, Fermeture val) {
				for (Depot depot : lst)
					if (depot.getDepot_p_id()==val.getdepot_fk_id())
						return true;
				return false;
		}};
		
		for (Fermeture fermeture : normalisedDepotAndFermeture.getFermetures())
			if (!foundIn.have(normalisedDepotAndFermeture.getDepots(), fermeture))
				fail("echec à l'integrité référentiel"+
			         " depot id " + fermeture.getdepot_fk_id() +
				     " fermeture id " + fermeture.getfermeture_p_id());			
	}
	
	@Test
	public void testDintegriteReferentielEntreFermetureEtEmploye(){
		Inside<Employe,Fermeture> foundIn = new Inside<Employe,Fermeture>(){
			@Override
			public boolean have(Iterable<Employe> lst, Fermeture val) {
				for (Employe employe : lst)
					if(employe.getemploye_p_id()== val.getemploye_fk_id())
						return true;
				return false;
			}
		};
		
		for (Fermeture fermeture : normalisedDepotAndFermeture.getFermetures())
			if (!foundIn.have(normalisedDepotAndFermeture.getEmployes(), fermeture))
				fail("echec à l'integrité référentiel"+
				         " employe id " + fermeture.getemploye_fk_id() +
					     " fermeture id " + fermeture.getfermeture_p_id());
	}
	
	@Test
	public void testDintegriteReferentielEntreEmployeEtUtilisateur(){
		Inside<Utilisateur,Employe> foundIn = new Inside<Utilisateur,Employe>(){
			@Override
			public boolean have(Iterable<Utilisateur> lst, Employe val) {
				for (Utilisateur utilisateur : lst)
					if (utilisateur.getutilisateur_p_id()==val.getUtilisateur_fk_id())
						return true;
				return false;
			}
		};
		
		for (Employe employe : normalisedDepotAndFermeture.getEmployes())
			if (!foundIn.have(normalisedDepotAndFermeture.getUtilisateurs(), employe))
				fail("echec à l'integrité référentiel"+
				         " employe id " + employe.getemploye_p_id() +
					     " utilisateur id " + employe.getUtilisateur_fk_id());	
	}
	
	@Test
	public void testDutilisateurOrphelin(){
		Inside<Employe, Utilisateur> foundIn = new Inside<Employe, Utilisateur>() {

			@Override
			public boolean have(Iterable<Employe> lst, Utilisateur val) {
				for (Employe employe : lst)
					if (val.getutilisateur_p_id()==employe.getUtilisateur_fk_id())
						return true;
				return false;
			}
		};
		
		for (Utilisateur utilisateur : normalisedDepotAndFermeture.getUtilisateurs())
			if (!foundIn.have(normalisedDepotAndFermeture.getEmployes(), utilisateur))
				fail("utilisateur Orphelin no "+ utilisateur.getutilisateur_p_id());
	}
	
	@Ignore
	@Test
	public void testDemployeOrphelin(){
		Inside<Depot, Employe> foundInDepot = new Inside<Depot, Employe>() {
			@Override
			public boolean have(Iterable<Depot> lst, Employe val) {
				for (Depot depot : lst)
					if (depot.getEmploye_fk_id()==val.getemploye_p_id())
						return true;
				return false;
			}
		};
		
		Inside<Fermeture, Employe> foundInFermeture = new Inside<Fermeture, Employe>() {
			@Override
			public boolean have(Iterable<Fermeture> lst, Employe val) {
				for (Fermeture fermeture : lst)
					if (fermeture.getemploye_fk_id()==val.getemploye_p_id())
						return true;
				return false;
			}
		};
		
		for (Employe employe : normalisedDepotAndFermeture.getEmployes())
			if (!foundInDepot.have(normalisedDepotAndFermeture.getDepots(), employe) &&
			    !foundInFermeture.have(normalisedDepotAndFermeture.getFermetures(), employe))
				fail("Employe Orphelin no "+ employe.getemploye_p_id());
	}
	
	@Ignore
	@Test
	public void testDeDepotOrphelin(){
		Inside<Fermeture, Depot> foundIn = new Inside<Fermeture, Depot>() {
			@Override
			public boolean have(Iterable<Fermeture> lst, Depot val) {
				for (Fermeture fermeture : lst)
					if (fermeture.getdepot_fk_id()==val.getDepot_p_id())
						return true;
				return false;
			}
		};
		
		for (Depot depot : normalisedDepotAndFermeture.getDepots()){
			if (!foundIn.have(normalisedDepotAndFermeture.getFermetures(), depot))
				fail("depot orphelin no "+ depot.getDepot_p_id());
		}
	}
	
	@Test
	public void testNotZero_depot_employe_fk_id(){
		for (Depot a : normalisedDepotAndFermeture.getDepots()){
			assertFalse("echec not zero employe de depot n " + a.getEmploye_fk_id(),a.getEmploye_fk_id()==0);
		}
	}
	
	@Test
	public void testNotZero_employe_utilisateur_fk_id(){
		for (Employe a : normalisedDepotAndFermeture.getEmployes()){
			assertFalse("echec not zero utilisateur de employe n " + a.getUtilisateur_fk_id(),a.getUtilisateur_fk_id()==0);
		}
	}
	
	@Test
	public void testNotZero_fermeture_depot_fk_id(){
		for (Fermeture a : normalisedDepotAndFermeture.getFermetures()){
			assertFalse("echec not zero depot de fermeture n " + a.getdepot_fk_id(),a.getdepot_fk_id()==0);
		}
	}
	
	@Test
	public void testNotZero_fermeture_employe_fk_id(){
		for (Fermeture a : normalisedDepotAndFermeture.getFermetures()){
			assertFalse("echec not zero employe de fermeture n " + a.getemploye_fk_id(),a.getemploye_fk_id()==0);
		}
	}
	
	@Test
	public void testNotZero_utilisateur_employe_fk_id(){
		for (Utilisateur a : normalisedDepotAndFermeture.getUtilisateurs()){
			assertFalse("echec not zero groupe utilisateur de utilisateur n " + a.getGroupe_utilisateur_fk_id(),a.getGroupe_utilisateur_fk_id()==0);
		}
	}
}
