from db_manager import db, VirtualMachine
from dotenv import load_dotenv
from pyVim import connect
from pyVmomi import vim
import logging
import ssl
import os

dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
load_dotenv(dotenv_path)


def get_database_uri():
    db_type = os.environ.get('DB_TYPE').lower()
    if db_type == "sqlite":
        return f"sqlite:///{os.environ.get('NAME_DB_SQLITE')}.db"
    elif db_type == "postgresql":
        return (f"postgresql://{os.environ.get('DB_USER')}:{os.environ.get('DB_PASS')}@"
                f"{os.environ.get('DB_HOST')}:{os.environ.get('DB_PORT')}/"
                f"{os.environ.get('DB_NAME')}")
    elif db_type == "mysql":
        return (f"mysql+mysqlconnector://{os.environ.get('DB_USER')}:"
                f"{os.environ.get('DB_PASS')}@{os.environ.get('DB_HOST')}:"
                f"{os.environ.get('DB_PORT')}/{os.environ.get('DB_NAME')}")
    else:
        logging.error('Неправильные настройки базы данных')


def disable_ssl_verification():
    ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    ssl_context.verify_mode = ssl.CERT_NONE
    return ssl_context


def connect_to_vcenter(host, user, password):
    try:
        service_instance = connect.SmartConnect(host=host, user=user, pwd=password,
                                                sslContext=disable_ssl_verification())
        return service_instance.RetrieveContent()
    except Exception as e:
        logging.error(f"Ошибка подключения к {host}: {e}")
        return None


def get_vm_info_and_save_to_db(content, hyper):
    try:
        container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
        vms = container.view
        for vm in vms:
            vm_config = vm.config

            existing_vm = VirtualMachine.query.filter_by(id_vm=vm._moId, hyper=hyper).first()
            if existing_vm:
                existing_vm.name = vm.name
                existing_vm.os = vm_config.guestFullName
                existing_vm.memory = vm_config.hardware.memoryMB
                existing_vm.cpu = vm_config.hardware.numCPU
                existing_vm.power_status = vm.runtime.powerState
                logging.info(f"Виртуальная машина {vm.name} обновлена.")
            else:
                new_vm = VirtualMachine(
                    hyper=hyper,
                    ip_addres=vm.summary.guest.ipAddress,
                    id_vm=vm._moId,
                    name=vm.name,
                    os=vm_config.guestFullName,
                    memory=vm_config.hardware.memoryMB,
                    cpu=vm_config.hardware.numCPU,
                    power_status=vm.runtime.powerState,
                    status='Свободно',
                    task='Свободно',
                    busy_date='Свободно'
                )
                logging.info(f"Новая виртуальная машина {vm.name} создана.")
                db.session.add(new_vm)

        db.session.commit()
    except Exception as e:
        logging.error(f"Ошибка при полном обновлении данных виртуальной машины: {e}")


def update_vm_power_status(content, hyper):
    try:
        container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualMachine], True)
        vms = container.view
        for vm in vms:
            existing_vm = VirtualMachine.query.filter_by(id_vm=vm._moId, hyper=hyper).first()
            if existing_vm:
                existing_vm.power_status = vm.runtime.powerState
                if existing_vm.ip_addres is None:
                    existing_vm.ip_addres = vm.summary.guest.ipAddress
        db.session.commit()
    except Exception as e:
        logging.error(f"Ошибка при обновлении статусов виртуальной машине: {e}")

