package br.edu.ifba.inf008.mediaCenter.persistencia;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import br.edu.ifba.inf008.mediaCenter.model.Servidor;
import br.edu.ifba.inf008.mediaCenter.model.ServidorBasico;
import br.edu.ifba.inf008.mediaCenter.model.ServidorReplicado;
import teste.TesteBancoDados;

public class ServidorDAOSQL implements ServidorDAO {

	public static final String URI = "jdbc:postgresql://localhost:5432/postgres"; 
	public static final String USER = "postgres";	
	public static final String PWD = "aluno";	
	public static final String INSERT_BASIC_SERVER = "INSERT INTO SERVIDOR_BASICO " + 
            								  	     "(id, latenciaLeitura, latenciaEscrita, " +
            									     "capacidadeOcupada, capacidadeTotal )  " +
            									     "VALUES(?, ?, ?, ?, ?)";

	public static final String INSERT_REP_SERVER = "INSERT INTO SERVIDOR_REPLICADO " + 
	  	     					"(id, id_interno)  " +
	  	     					"VALUES(?, ?)";
	
	
	public static final String SELECT_BASIC_SERVER = "SELECT id, latenciaLeitura, " + 
			                                		  "latenciaEscrita, capacidadeOcupada, " +
			                                		  "capacidadeTotal " +
			                                		 "FROM  SERVIDOR_BASICO ";

	public static final String SELECT_BASIC_BYID = "SELECT id, latenciaLeitura, " + 
  		  									       "latenciaEscrita, capacidadeOcupada, " +
  		  									       "capacidadeTotal " +
  		  									       "FROM  SERVIDOR_BASICO " +
  		  									       "WHERE id = ?";
	
	
	public ServidorDAOSQL() throws SQLException{
		DriverManager.registerDriver(new org.postgresql.Driver());
	}
	
	
	public Connection getConn() throws SQLException{
		return DriverManager.getConnection(ServidorDAOSQL.URI,
									       ServidorDAOSQL.USER, ServidorDAOSQL.PWD);
	}
	
	
	@Override
	public Collection<Servidor> findAll() throws Exception {
		Collection<Servidor> servidores = new HashSet<Servidor>();
		Collection<ServidorBasico> servidoresBasicos = this.getServidoresBasicos();
		
		
		return servidores;
		
	}

	@Override
	public void save(Servidor servidor) throws Exception {
		if(servidor instanceof ServidorBasico)
			this.saveServidorBasico((ServidorBasico) servidor);
		else if(servidor instanceof ServidorReplicado)
			this.saveServidorReplicado((ServidorReplicado) servidor);
	}


	private void saveServidorBasico(ServidorBasico servidor) throws SQLException {
		Connection conn = this.getConn();
		PreparedStatement pStmt = conn.prepareStatement(INSERT_BASIC_SERVER);
		pStmt.setString(1, servidor.getId());
		pStmt.setDouble(2, servidor.getLatenciaLeitura());
		pStmt.setDouble(3, servidor.getLatenciaEscrita());
		pStmt.setLong(4, servidor.getCapacidadeOcupada());
		pStmt.setLong(5, servidor.getCapacidadeTotal());
		pStmt.executeUpdate();
		pStmt.close();
		conn.close();
	}
	
	private void saveServidorReplicado(ServidorReplicado servidor) throws Exception {
		for(Servidor s : servidor.getServidores()){
			this.doSave(servidor, s);
			this.save(s);
		}
	}
	
	private void doSave(Servidor externo, Servidor interno) throws SQLException{
		Connection conn = this.getConn();
		PreparedStatement pStmt = conn.prepareStatement(INSERT_REP_SERVER);
		pStmt.setString(1, externo.getId());
		pStmt.setString(2, interno.getId());
		pStmt.executeUpdate();
		pStmt.close();
		conn.close();
	}
	
	private Collection<ServidorBasico> getServidoresBasicos() throws SQLException{
		Collection<ServidorBasico> servidores = new HashSet<ServidorBasico>();
		Connection conn = this.getConn();
		PreparedStatement pStmt = conn.prepareStatement(SELECT_BASIC_SERVER);
		ResultSet rSet = pStmt.executeQuery();
		while(rSet.next()) {
			ServidorBasico servidor = new ServidorBasico(rSet.getString("id"), 
											             rSet.getLong("capacidadeTotal"), 
											             rSet.getDouble("latenciaLeitura"), 
											             	rSet.getDouble("latenciaEscrita"));
			servidores.add(servidor);
		}
		rSet.close();
		return servidores;
	}
	
	private ServidorBasico getServidorBasicoById(String id) throws SQLException{
		ServidorBasico servidor = null;
		Connection conn = this.getConn();
		PreparedStatement pStmt = conn.prepareStatement(SELECT_BASIC_BYID);
		pStmt.setString(1, id);
		ResultSet rSet = pStmt.executeQuery();
		if(rSet.next()) {
			servidor = new ServidorBasico(rSet.getString("id"), 
							             rSet.getLong("capacidadeTotal"), 
							             rSet.getDouble("latenciaLeitura"), 
						             	rSet.getDouble("latenciaEscrita"));
		}
		rSet.close();
		return servidor;
	}
	
	

}
