
package paqueteBL;

import java.util.ArrayList;
import java.util.List;
import paqueteDAO.BackupDAO;
import paqueteDAO.EventoDAO;
import paqueteDAO.HostDAO;
import paqueteDAO.PoolDAO;
import paqueteDAO.VmDAO;
import paqueteVIX.OP;
import paqueteVIX.VIX;

public class FvcBL {

    
    private VMext cambiarEstadoVM(int id, int nuevoEstado) throws Exception
    {
        VmDAO vmd=new VmDAO();
        VMext vm=vmd.read(id);
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        evento.setEvento(VM.getStrEstado(nuevoEstado)+" "+vm.getNombre());
        evento.setIdVM(vm.getId());
        evento.setIdHost(vm.getIdHost());
        ed.insert(evento);
        vmd.updateEstado(id, nuevoEstado);
        vm=loadCompletaVM(id);

        VIX x=new VIX();
        String operacion="";
        if (nuevoEstado==VM.ESTADO_STARTING) operacion="START_VM";
        else if (nuevoEstado==VM.ESTADO_STOPING)  operacion="STOP_VM";
        x.encolaOP_asincronona(new OP(operacion,vm));
        x.start();

        return vm;
    }

    public VMext stopVM(int id) throws Exception
    {
        return cambiarEstadoVM(id,VM.ESTADO_STOPING);
    }

    public VMext startVM(int id) throws Exception
    {
        return cambiarEstadoVM(id,VM.ESTADO_STARTING);
    }

    public VMext loadVM(int id) throws Exception
    {
        VMext vm=new VMext();
        VmDAO vmd=new VmDAO();
        EventoDAO ed=new EventoDAO();
        vm=vmd.read(id);
        vm.setEventos(ed.findEventosByVM(id,5));
        BackupDAO bd=new BackupDAO();
        vm.setBackups(bd.findBackupsByVM(id,5));
        return vm;
    }

    public VMext loadCompletaVM(int id) throws Exception
    {
        VMext vm;
        vm=loadVM(id);
        HostDAO dh=new HostDAO();
        HostExt host=dh.read(vm.getIdHost());
        vm.setHost(host);
        return vm;
    }

    public HostExt loadCompletoHost(int id) throws Exception
    {
        HostDAO dh=new HostDAO();
        HostExt host=dh.read(id);
        EventoDAO ed=new EventoDAO();
        host.setEventos(ed.findEventosByHost(id,10));
        return host;
    }
    
    public List<HostExt> loadHosts() throws Exception
    {
        HostDAO dh=new HostDAO();
        return dh.findByQuery("select * from host");
    }

    public List<VMext> loadVMs() throws Exception
    {
        VmDAO vmd=new VmDAO();
        return vmd.findByQuery("select * from vm");
    }

    public List<VMext> findVMbyHost(Host host)
    {
        VIX vix=new VIX();
        return vix.findVMbyHost(host);
    }

    public void startVM2(VMext vm)
    {
        VIX vix=new VIX();
        vix.startVM(vm);
    }

    public Pool loadPool() throws Exception
    {
        PoolDAO pd=new PoolDAO();
        Pool pool=pd.read();
        EventoDAO ed=new EventoDAO();
        List<Evento> listaEventos=ed.findEventosByPool(4);
        pool.setEventos(listaEventos);
        return pool;
    }

    public HostExt updateHost(Host host) throws Exception
    {
        HostDAO dh=new HostDAO();
        dh.update(host);
        HostExt hostEx=new HostExt(host);
        EventoDAO ed=new EventoDAO();
        hostEx.setEventos(ed.findEventosByHost(host.getId(),10));
        return hostEx;
    }

    public HostExt addHost(Host host) throws Exception
    {
        HostDAO dh=new HostDAO();
        dh.insert(host);
        HostExt hostEx=new HostExt(host);
        Evento evento=addEvento(host.getId(),0,"AÑADIDO al pool "+host.getNombre());
        hostEx.addEvento(evento);
        return hostEx;
    }

    public Evento addEvento(int idHost,int idVM,String mensaje) throws Exception
    {
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        evento.setEvento(mensaje);
        evento.setIdVM(idVM);
        evento.setIdHost(idHost);
        ed.insert(evento);
        return evento;
    }

    public Pool updatePool(Pool pool) throws Exception
    {
        PoolDAO pd=new PoolDAO();
        pd.update(pool);
        return pool;
    }

    public HostExt mantenimientoHOST(int id) throws Exception
    {
        HostDAO hd=new HostDAO();
        HostExt host=hd.read(id);
        hd.updateEstado(id, Host.ESTADO_MANTENIMIENTO);
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        evento.setEvento("MANTENIMIENTO de "+host.getNombre());
        evento.setIdVM(0);
        evento.setIdHost(host.getId());
        ed.insert(evento);

        List<HostExt> lstDestino=hd.findByQuery("select * from host where estado="+Host.ESTADO_DISPONIBLE);
        HostExt destino=lstDestino.get(0);
        List<VMext> maquinas=findVMbyHost(destino);
        int i;
        for(i=0;i<maquinas.size();i++) migrarVM(maquinas.get(i).getId(),destino.getId());

        host=loadCompletoHost(id);
        return host;
    }

    public HostExt salirMantenimientoHOST(int id) throws Exception
    {
        HostDAO hd=new HostDAO();
        HostExt host=hd.read(id);
        hd.updateEstado(id, Host.ESTADO_DISPONIBLE);
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        evento.setEvento("MODO NORMAL en "+host.getNombre());
        evento.setIdVM(0);
        evento.setIdHost(host.getId());
        ed.insert(evento);
        host=loadCompletoHost(id);
        return host;
    }

    public VMext migrarVM(int id,int idTarget) throws Exception
    {
        VmDAO vmd=new VmDAO();
        VMext vm=vmd.read(id);
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        evento.setEvento("MIGRANDO "+vm.getNombre());
        evento.setIdVM(vm.getId());
        evento.setIdHost(vm.getIdHost());
        ed.insert(evento);
        HostDAO hd=new HostDAO();
        Host target=hd.read(idTarget);
        VIX x=new VIX();
        x.encolaOP_asincronona(new OP("PAUSE",vm));
        x.encolaOP_asincronona(new OP("UNREGISTER",vm));
        x.encolaOP_asincronona(new OP("REGISTER",vm,target));
        VMext vmt=(VMext)vm.clone();
        vmt.setHost(target);
        vmt.setEstado(VM.ESTADO_MIGRANDO);
        vmd.update(vmt);
        x.encolaOP_asincronona(new OP("PLAY",vm));
        x.start();
        vmt=loadCompletaVM(id);
        return vmt;
    }

    public VMext clonarVM(int id,String target) throws Exception
    {
        VmDAO vmd=new VmDAO();
        VMext vm=vmd.read(id);
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        evento.setEvento("CLONADO "+vm.getNombre());
        evento.setIdVM(vm.getId());
        evento.setIdHost(vm.getIdHost());
        ed.insert(evento);
        vmd.updateEstado(id, VM.ESTADO_CLONANDO);
        VIX x=new VIX();
        x.encolaOP_asincronona(new OP("CLONE",vm,target));
        x.start();
        VMext vmt=(VMext)vm.clone();
        vmt.setNombre(target);
        vmd.insert(vmt);
        vm=loadCompletaVM(id);
        return vm;
    }

    public VMext desplegarVM(int id,int idHost,String target) throws Exception
    {
        VmDAO vmd=new VmDAO();
        VMext vm=vmd.read(id);
        EventoDAO ed=new EventoDAO();
        Evento evento=new Evento();
        HostDAO hd=new HostDAO();
        Host host=hd.read(idHost);
        VMext maq=new VMext();
        maq.setNombre(target);
        maq.setHost(host);
        vmd.insert(maq);
        evento.setEvento("DESPLEGANDO "+target);
        evento.setIdVM(maq.getId());
        evento.setIdHost(maq.getIdHost());
        ed.insert(evento);
        vmd.updateEstado(id,VM.ESTADO_STOP);
        VIX x=new VIX();
        vm.setHost(host);
        x.encolaOP_asincronona(new OP("CLONE",vm,target));
        x.start();
        maq=loadCompletaVM(maq.getId());
        return maq;
    }


    public VMext updateVM(VM vm) throws Exception
    {
        VmDAO vd=new VmDAO();
        vd.update(vm);
        return loadVM(vm.getId());
    }

    

}
