package org.mte.numecoeval.calculs.infrastructure.repository;

import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.calculs.domain.data.entree.EquipementVirtuel;
import org.mte.numecoeval.calculs.domain.exception.DatabaseException;
import org.mte.numecoeval.common.utils.ResultSetUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class EquipementVirtuelRepository {

    @Autowired
    private DataSource dataSource;

    public List<EquipementVirtuel> findEquipementVirtuels(String nomOrganisation, String nomLot, String nomEquipementPhysique) {
        List<EquipementVirtuel> result = new ArrayList<>();

        try (Connection conn = dataSource.getConnection()) {
            try (var ps = conn.prepareStatement("""
                     SELECT *
                     FROM en_equipement_virtuel
                     WHERE
                         nullif(nom_lot, ?) is null
                         AND nom_equipement_physique = ?
                         AND nullif(nom_organisation, ?) is null
                    """)) {

                ps.setString(1, nomLot);
                ps.setString(2, nomEquipementPhysique);
                ps.setString(3, nomOrganisation);

                var rs = ps.executeQuery();
                while (rs.next()) {
                    result.add(EquipementVirtuel.builder()
                            .id(rs.getLong("id"))
                            .nomLot(rs.getString("nom_lot"))
                            .dateLot(ResultSetUtils.getLocalDate(rs, "date_lot"))
                            .nomOrganisation(rs.getString("nom_organisation"))
                            .nomEntite(rs.getString("nom_entite"))
                            .nomEquipementPhysique(rs.getString("nom_equipement_physique"))
                            .nomEquipementVirtuel(rs.getString("nom_equipement_virtuel"))
                            .cluster(rs.getString("cluster"))
                            .vCPU(ResultSetUtils.getInteger(rs, "vcpu"))
                            .consoElecAnnuelle(ResultSetUtils.getDouble(rs, "conso_elec_annuelle"))
                            .typeEqv(rs.getString("type_eqv"))
                            .capaciteStockage(ResultSetUtils.getDouble(rs, "capacite_stockage"))
                            .cleRepartition(ResultSetUtils.getDouble(rs, "cle_repartition"))
                            .nomSourceDonnee(rs.getString("nom_source_donnee"))
                            .build());
                }
            }
        } catch (SQLException e) {
            log.error("Une erreur s'est produite lors de la selection dans PostgreSQL. Exception: ", e);
            throw new DatabaseException(e);
        }

        return result;
    }
}
