/* 
* Copyright 2016 Agencia Estatal de Administración Tibutaria
*
* Licencia con arreglo a la EUPL, Versión 1.1 o –en cuanto
* sean aprobadas por la Comisión Europea– versiones
* posteriores de la EUPL (la «Licencia»);
* Solo podrá usarse esta obra si se respeta la Licencia.
* Puede obtenerse una copia de la Licencia en:
*  
* https://joinup.ec.europa.eu/software/page/eupl
*  
* Salvo cuando lo exija la legislación aplicable o se acuerde
* por escrito, el programa distribuido con arreglo a la
* Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES
* DE NINGÚN TIPO, ni expresasni implícitas.
*
* Véase la Licencia en el idioma concreto que rige los permisos y 
* limitaciones que establece la Licencia.
*/ 

package servidor.datos;

import java.sql.*;
import java.sql.Statement;

public class ActualizadorEstructuraBD implements InterfacesAteneo.IActualizadorBDAteneo {

    BaseDatos bd;

    public ActualizadorEstructuraBD() {
        bd = BaseDatos.bd();
    }

    @Override
    public void comprobarTablas() {
        bd.abrirSiCerrada();
        try {
            comprobarTablaRangoHuecos();
            comprobarTablaconfSer();
            comprobarTablaCategoriasEsta();
            comprobarTablaServicios();
            comprobarTablaCandidatos();
            comprobarTablaAccionesHoy();
            comprobarTablaHistoricoCandidatos();
            // comprobarTablaOperadores();
            comprobarTablaColas();
            comprobarTablaHuecos();
            comprobarTablaGeneradorCitas();
            comprobarTablaMensajesGestores();
            comprobarTablaProductos();
        } catch (Exception exc) {
            exc.printStackTrace();
        }
    }

    void comprobarTablaRangoHuecos() {
        try {
            if (!existe("RangoHuecos")) {
                String sq = "CREATE TABLE RangoHuecos ([Id] int IDENTITY(1, 1) NOT NULL, [Origen] nvarchar(2) NOT NULL, [Destino] nvarchar(2) NOT NULL, UNIQUE ([Origen]))";
                bd.SQL(sq);
            }
        } catch (Exception exc) {
        }
    }

    void comprobarTablaconfSer() {
        try {
            if (!existe("confiSer")) {
                String sq = "CREATE TABLE confiSer ([parametro] nvarchar(50) NULL,   [valor] nvarchar(200) NULL )";
                bd.SQL(sq);
            }
        } catch (Exception exc) {
        }
    }

    void comprobarTablaCategoriasEsta() throws Exception {
        if (!existe("CategoriasEsta")) {
            javax.swing.JOptionPane.showMessageDialog(null, "No se ha creado la tabla Categorias\nEjecute el módulo ConfiguraServidor");
            servidor.utiles.Global.main.cerrarAplicacionSinEsperar();
        }
    }

    void comprobarTablaServicios() throws Exception {
//      if (!existe("Servicios")) {
//         String sq = "CREATE TABLE [dbo].[Servicios] ([Codigo] int NOT NULL,"
//                 + "[Descripcion] nvarchar(70) CONSTRAINT [DF_Servicios_Descripcion] DEFAULT '' NULL,"
//                 + "[CodigoEstadistico] nvarchar(2) CONSTRAINT [DF_Servicios_CodigoEstadistico] DEFAULT '' NULL,"
//                 + "[Activo] bit CONSTRAINT [DF_Servicios_Activo] DEFAULT 1 NULL,"
//                 + "[ColasAsociadas] nvarchar(50) CONSTRAINT [DF_Servicios_ColasAsociadas] DEFAULT '' NULL,"
//                 + "[Huecos] bit DEFAULT 1 NOT NULL,"
//                 + " CONSTRAINT [PK_Servicios] PRIMARY KEY NONCLUSTERED ([Codigo]))";
//         bd.SQL(sq);
//      }
//      Esquema esq = new Esquema("Servicios");
//      if (esq.numColumnas() < 6) {
//         bd.SQL("ALTER TABLE Servicios ADD [Huecos] bit DEFAULT 1 NOT NULL");
//      }
//      return;
    }

    void comprobarTablaCandidatos() throws Exception {
//      Esquema esq = new Esquema("candidatos");
//      if (esq.ancho("indicadores") < 50) {
//         bd.SQL("ALTER TABLE Candidatos ALTER COLUMN Indicadores nvarchar(50)");
//      }
//      if (esq.ancho("cola") < 2) {
//         bd.SQL("ALTER TABLE Candidatos ALTER COLUMN Cola nvarchar(2)");
//      }
//      if (esq.numColumnas() < 28) {
//         bd.SQL("ALTER TABLE Candidatos ADD [HoraPresente2] datetime NULL");
//      }
//      if (esq.numColumnas() < 31) {
//         bd.SQL("ALTER TABLE Candidatos ADD [NifConyuge] nvarchar(9)");
//         bd.SQL("ALTER TABLE Candidatos ADD [NiuConyuge] nvarchar(11)");
//         bd.SQL("ALTER TABLE Candidatos ADD [ApeConyuge] nvarchar(3)");
//      }
//      if (esq.numColumnas() < 34) {
//         bd.SQL("ALTER TABLE Candidatos ADD [NombreCola] nvarchar(25)");
//         bd.SQL("ALTER TABLE Candidatos ADD [GHuecos] bit DEFAULT 0");
//         bd.SQL("ALTER TABLE Candidatos ADD [DNIe] bit DEFAULT 0");
//      }
    }

    void comprobarTablaAccionesHoy() throws Exception {
//      Esquema esq = new Esquema("accionesHoy");
//      if (esq.ancho("puesto") < 3) {
//         bd.SQL("ALTER TABLE AccionesHoy ALTER COLUMN Puesto nvarchar(3)");
//         bd.SQL("ALTER TABLE HistoricoAcciones ALTER COLUMN Puesto nvarchar(3)");
//      }
    }

    void comprobarTablaHistoricoCandidatos() throws Exception {
//      Esquema esq = new Esquema("historicoCandidatos");
//      if (esq.ancho("indicadores") < 50) {
//         bd.SQL("ALTER TABLE HistoricoCandidatos ALTER COLUMN Indicadores nvarchar(50)");
//      }
//      if (esq.ancho("cola") < 2) {
//         bd.SQL("ALTER TABLE HistoricoCandidatos ALTER COLUMN Cola nvarchar(2)");
//      }
//      if (esq.ancho("citavinculada") < 19) {
//         bd.SQL("ALTER TABLE HistoricoCandidatos ALTER COLUMN citaVinculada nvarchar(19)");
//      }
//      if (esq.numColumnas() < 28) {
//         bd.SQL("ALTER TABLE HistoricoCandidatos ADD [HoraPresente2] datetime NULL");
//      }
//      if (esq.numColumnas() < 31) {
//         bd.SQL("ALTER TABLE HistoricoCandidatos ADD [NifConyuge] nvarchar(9)");
//         bd.SQL("ALTER TABLE HistoricoCandidatos ADD [NiuConyuge] nvarchar(11)");
//         bd.SQL("ALTER TABLE HistoricoCandidatos ADD [ApeConyuge] nvarchar(3)");
//      }
//      if (esq.numColumnas() < 34) {
//         bd.SQL("ALTER TABLE  HistoricoCandidatos ADD [NombreCola] nvarchar(25)");
//         bd.SQL("ALTER TABLE  HistoricoCandidatos ADD [GHuecos] bit DEFAULT 0");
//         bd.SQL("ALTER TABLE  HistoricoCandidatos ADD [DNIe] bit DEFAULT 0");
//      }
//   }
//
//   void comprobarTablaOperadores() throws Exception {
//      Esquema esq = new Esquema("operadores");
//      if (esq.numColumnas() < 6) {
//         bd.SQL("ALTER TABLE Operadores ADD [Favoritas] nvarchar(100) NULL");
//      }
//      if (esq.numColumnas() < 7) {
//         bd.SQL("ALTER TABLE Operadores ADD [Suplencias] nvarchar(100) NULL");
//      }
//      if (esq.numColumnas() < 8) {
//         bd.SQL("ALTER TABLE Operadores ADD [FavEstadisticas] nvarchar(150) NULL");
//      }
    }

    void comprobarTablaColas() throws Exception {
        Esquema esq = new Esquema("colas");
//      if (esq.ancho("cola") < 2) {
//         try {
//            bd.SQL("ALTER TABLE [dbo].[Colas] DROP CONSTRAINT [DF__TemporaryU__Cola__29572725]");
//         } catch (Exception exc) {
//         }
//         try {
//            bd.SQL("DROP INDEX [dbo].[Colas].[Cola]");
//         } catch (Exception exc) {
//         }
//         bd.SQL("ALTER TABLE [dbo].[Colas] ALTER COLUMN [Cola] nvarchar(2)");
//         bd.SQL("ALTER TABLE [dbo].[Colas] ADD CONSTRAINT [DF__TemporaryU__Cola__29572725] DEFAULT '0' FOR [Cola]");
//         bd.SQL("CREATE UNIQUE NONCLUSTERED INDEX Cola ON Colas (Cola)ON [PRIMARY]");
//      }
//      if (esq.numCol("codigoServicio") != -1) {
//         bd.SQL("EXEC sp_rename '[dbo].[Colas].[codigoServicio]', 'UmbralSuplencia', 'COLUMN'");
//      }
//      if (esq.numCol("NifObligatorio") == -1) {
//         bd.SQL("ALTER TABLE [dbo].[Colas] ADD [NifObligatorio] bit DEFAULT 0 NOT NULL");
//      }
//      if (esq.numCol("ColaEspecial") == -1) {
//         bd.SQL("ALTER TABLE [dbo].[Colas] ADD [ColaEspecial] bit DEFAULT 0 NOT NULL");
//      }
        if (esq.numCol("HuecosOpe") == -1) {
            bd.SQL("ALTER TABLE [dbo].[Colas] ADD [HuecosOpe] bit DEFAULT 1 NOT NULL");
        }
    }

    void comprobarTablaHuecos() throws Exception {
        if (!existe("huecos")) {
            bd.SQL("CREATE TABLE Huecos( [Id] int IDENTITY NOT NULL, [HoraCita] datetime NULL, "
                    + "[Cola] nvarchar(2) NULL, [Turno] nvarchar(1) NULL)");
            bd.SQL("ALTER TABLE Huecos ADD CONSTRAINT [aaaaaHuecos_PK] PRIMARY KEY NONCLUSTERED ([Id]) ON [PRIMARY]");
        }
    }

    void comprobarTablaGeneradorCitas() throws Exception {
        if (!existe("GeneradorCitas")) {
            bd.SQL("CREATE TABLE [dbo].[GeneradorCitas] ([Cola] nvarchar(2) NOT NULL,[Turno] nvarchar(1) NULL,"
                    + "[HoraInicio] datetime NOT NULL,[HoraFin] datetime NOT NULL,[Duracion] int NULL, [Puestos] int NULL,"
                    + "[UltimaEjecucion] datetime NULL)");
            bd.SQL("ALTER TABLE Generadorcitas ADD CONSTRAINT [GeneradorCitas_pk] PRIMARY KEY CLUSTERED ([Cola], [HoraInicio], [HoraFin]) ON [PRIMARY]");
        }
    }

    void comprobarTablaMensajesGestores() throws Exception {
        if (!existe("mensajesGestores")) {
            bd.SQL("CREATE TABLE [dbo].[mensajesGestores] ("
                    + "[Id] int IDENTITY(1, 1) NOT NULL,"
                    + "[hora] datetime NULL,"
                    + "[codigo] int NULL,"
                    + "[mensaje] nvarchar(300) NULL,"
                    + "[gestor] nvarchar(15) NULL,"
                    + "PRIMARY KEY CLUSTERED ([Id]))");
        }
    }

    void comprobarTablaProductos() throws Exception {
        if (!existe("Productos")) {
            bd.SQL("CREATE TABLE [Productos] ("
                    + "[fecha] datetime NULL,"
                    + "[operador] nvarchar(15) NULL,"
                    + "[mesa] nvarchar(10) NULL,"
                    + "[nif] nvarchar(9) NULL,"
                    + "[nombreProcedimiento] nvarchar(50) NULL,"
                    + "[datos] nvarchar(250) NULL)");
        }
    }

    public boolean existe(String tabla) {
        try {
            Statement stmt = bd.conexion.createStatement();
            stmt.executeQuery("SELECT TOP 1 * FROM " + tabla);
            stmt.close();
            return true;
        } catch (Exception exc) {
            return false;
        }
    }

    class Esquema {

        public ResultSetMetaData md;
        public String[] nombres;

        public Esquema(String tabla) throws Exception {
            Statement stmt = BaseDatos.bd().conexion.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT TOP 1 * FROM " + tabla);
            md = rs.getMetaData();
            nombres = new String[md.getColumnCount() + 1];
            for (int i = 1; i < nombres.length; i++) {
                nombres[i] = md.getColumnName(i).toLowerCase();
            }
            stmt.close();
        }

        public int numCol(String nombre) {
            nombre = nombre.toLowerCase();
            for (int i = 1; i < nombres.length; i++) {
                if (nombres[i].equals(nombre)) {
                    return i;
                }
            }
            return -1;
        }

        public int numColumnas() {
            return nombres.length - 1;
        }

        public int ancho(String columna) throws Exception {
            return md.getPrecision(numCol(columna));
        }
    }
}
