"""Support for Proxmox VE."""
from enum import Enum
import logging

from proxmoxer import ProxmoxAPI
from proxmoxer.backends.https import AuthenticationError
from requests.exceptions import SSLError
import voluptuous as vol

from homeassistant.const import (
    CONF_HOST,
    CONF_PASSWORD,
    CONF_PORT,
    CONF_USERNAME,
    CONF_VERIFY_SSL,
)
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)


DOMAIN = "proxmoxve"
PROXMOX_CLIENTS = "proxmox_clients"
CONF_REALM = "realm"
CONF_NODE = "node"
CONF_NODES = "nodes"
CONF_VMS = "vms"
CONF_CONTAINERS = "containers"

DEFAULT_PORT = 8006
DEFAULT_REALM = "pam"
DEFAULT_VERIFY_SSL = True

CONFIG_SCHEMA = vol.Schema(
    {
        DOMAIN: vol.All(
            cv.ensure_list,
            [
                vol.Schema(
                    {
                        vol.Required(CONF_HOST): cv.string,
                        vol.Required(CONF_USERNAME): cv.string,
                        vol.Required(CONF_PASSWORD): cv.string,
                        vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
                        vol.Optional(CONF_REALM, default=DEFAULT_REALM): cv.string,
                        vol.Optional(
                            CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL
                        ): cv.boolean,
                        vol.Required(CONF_NODES): vol.All(
                            cv.ensure_list,
                            [
                                vol.Schema(
                                    {
                                        vol.Required(CONF_NODE): cv.string,
                                        vol.Optional(CONF_VMS, default=[]): [
                                            cv.positive_int
                                        ],
                                        vol.Optional(CONF_CONTAINERS, default=[]): [
                                            cv.positive_int
                                        ],
                                    }
                                )
                            ],
                        ),
                    }
                )
            ],
        )
    },
    extra=vol.ALLOW_EXTRA,
)


def setup(hass, config):
    """Set up the component."""

    # Create API Clients for later use
    hass.data[PROXMOX_CLIENTS] = {}
    for entry in config[DOMAIN]:
        host = entry[CONF_HOST]
        port = entry[CONF_PORT]
        user = entry[CONF_USERNAME]
        realm = entry[CONF_REALM]
        password = entry[CONF_PASSWORD]
        verify_ssl = entry[CONF_VERIFY_SSL]

        try:
            # Construct an API client with the given data for the given host
            proxmox_client = ProxmoxClient(
                host, port, user, realm, password, verify_ssl
            )
            proxmox_client.build_client()
        except AuthenticationError:
            _LOGGER.warning(
                "Invalid credentials for proxmox instance %s:%d", host, port
            )
            continue
        except SSLError:
            _LOGGER.error(
                'Unable to verify proxmox server SSL. Try using "verify_ssl: false"'
            )
            continue

        hass.data[PROXMOX_CLIENTS][f"{host}:{port}"] = proxmox_client

    if hass.data[PROXMOX_CLIENTS]:
        hass.helpers.discovery.load_platform(
            "binary_sensor", DOMAIN, {"entries": config[DOMAIN]}, config
        )
        return True

    return False


class ProxmoxItemType(Enum):
    """Represents the different types of machines in Proxmox."""

    qemu = 0
    lxc = 1


class ProxmoxClient:
    """A wrapper for the proxmoxer ProxmoxAPI client."""

    def __init__(self, host, port, user, realm, password, verify_ssl):
        """Initialize the ProxmoxClient."""

        self._host = host
        self._port = port
        self._user = user
        self._realm = realm
        self._password = password
        self._verify_ssl = verify_ssl

        self._proxmox = None
        self._connection_start_time = None

    def build_client(self):
        """Construct the ProxmoxAPI client. Allows inserting the realm within the `user` value."""

        if "@" in self._user:
            user_id = self._user
        else:
            user_id = f"{self._user}@{self._realm}"

        self._proxmox = ProxmoxAPI(
            self._host,
            port=self._port,
            user=user_id,
            password=self._password,
            verify_ssl=self._verify_ssl,
        )

    def get_api_client(self):
        """Return the ProxmoxAPI client."""
        return self._proxmox