package versao2.persistencia.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import versao2.dominio.Cliente;
import versao2.persistencia.ClienteDAO;
import versao2.persistencia.DAO;
import versao2.persistencia.DAOFactory;
import versao2.persistencia.DBUtil;
import versao2.persistencia.PedidoDAO;

/**
 * Implementacao do objeto de acesso a dados de cliente.
 *
 * @see versao2.persistencia.ClienteDAO
 */
public final class ClienteDAOImpl
    implements ClienteDAO {

  /*
     Singleton de escopo limitado
     Note que apesar de possuir uma unica instancia desta clase,
     este objeto nao e global.
     Como getInstance e um metodo protegido,
     apenas membros do mesmo pacote podem obter instancias dele diretamente.
   */
  private static ClienteDAOImpl instance;

  static{
    instance = new ClienteDAOImpl();
  }

  protected static ClienteDAO getInstance(){
    return instance;
  }

  private ClienteDAOImpl(){}

  private void update(Cliente cliente) throws SQLException {
    Connection conn = DBUtil.getConnection();
    PreparedStatement pstmt = conn.
        prepareStatement("UPDATE CLIENTE SET NOME = ? WHERE CLIENTEID = ?");
    pstmt.setString(1, cliente.getNome());
    pstmt.setLong(2, cliente.getClienteId());
    pstmt.executeUpdate();
    conn.close();
  }

  public void save(Cliente cliente) throws SQLException {
    if (cliente.getClienteId() == UNSAVED) {
      create(cliente);
    }
    else {
      update(cliente);
    }
  }

  public void remove(Cliente cliente) throws SQLException {
    DAOFactory daoFactory = new DAOFactoryImpl();
    PedidoDAO pedidoDAO = daoFactory.createPedidoDAO();
    pedidoDAO.removerPorCliente(cliente);
    Connection conn = DBUtil.getConnection();
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("DELETE FROM CLIENTE WHERE CLIENTEID=" +
                       cliente.getClienteId());
    cliente.setClienteId(UNSAVED);
    conn.close();
  }

  public List buscarTodos() throws SQLException {
    List result = new ArrayList();
    Cliente cliente = null;

    Connection conn = DBUtil.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM CLIENTE");

    while (rs.next()) {
      cliente = new Cliente();
      cliente.setClienteId(rs.getLong("CLIENTEID"));
      cliente.setNome(rs.getString("NOME"));
      result.add(cliente);
    }
    conn.close();
    return result;
  }

  public void removerTodos() throws SQLException {
    Connection conn = DBUtil.getConnection();
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("DELETE FROM ITEM");
    stmt.executeUpdate("DELETE FROM PEDIDO");
    stmt.executeUpdate("DELETE FROM CLIENTE");
    conn.close();
  }

  private void create(Cliente cliente) throws SQLException {
    Connection conn = DBUtil.getConnection();
    PreparedStatement pstmt = conn.
        prepareStatement("INSERT INTO CLIENTE(NOME) VALUES (?)");
    pstmt.setString(1, cliente.getNome());
    pstmt.executeUpdate();
    ResultSet rs = pstmt.getGeneratedKeys();
    if (rs.next()) {
      cliente.setClienteId(rs.getLong(1));
    }
    conn.close();
  }

}
