import logging
from typing import Dict, List, NamedTuple, Union, cast

from paramiko.ssh_exception import AuthenticationException

from .fuel_rest_api import get_cluster_id, reflect_cluster, FuelInfo, KeystoneAuth
from .ssh_utils import ConnCreds
from .utils import StopTestError, parse_creds, to_ip
from .stage import Stage, StepOrder
from .test_run_class import TestRun
from .node import connect, setup_rpc
from .config import ConfigBlock
from .openstack_api import OSCreds


logger = logging.getLogger("wally")


FuelNodeInfo = NamedTuple("FuelNodeInfo",
                          [("version", List[int]),
                           ("fuel_ext_iface", str),
                           ("openrc", Dict[str, Union[str, bool]])])



class DiscoverFuelStage(Stage):
    """"Fuel nodes discovery, also can get openstack openrc"""

    priority = StepOrder.DISCOVER
    config_block = 'fuel'

    @classmethod
    def validate(cls, cfg: ConfigBlock) -> None:
        # msg = "openstack_env should be provided in fuel config"
        # check_input_param('openstack_env' in fuel_data, msg)
        # fuel.openstack_env
        pass

    def run(self, ctx: TestRun) -> None:
        full_discovery = 'fuel' in ctx.config.discover
        metadata_only = (not full_discovery) and ('metadata' in ctx.config.discover)
        ignore_errors = 'ignore_errors' in ctx.config.discover

        if not (metadata_only or full_discovery):
            logger.debug("Skip ceph discovery due to config setting")
            return

        if "fuel_os_creds" in ctx.storage and 'fuel_version' in ctx.storage:
            logger.debug("Skip FUEL credentials discovery, use previously discovered info")
            ctx.fuel_openstack_creds = OSCreds(*cast(List, ctx.storage.get('fuel_os_creds')))
            ctx.fuel_version = ctx.storage.get('fuel_version')
            if 'all_nodes' in ctx.storage:
                logger.debug("Skip FUEL nodes discovery, use data from DB")
                return
            elif metadata_only:
                logger.debug("Skip FUEL nodes  discovery due to discovery settings")
                return

        fuel = ctx.config.fuel
        fuel_node_info = ctx.merge_node(fuel.ssh_creds, {'fuel_master'})
        creds = dict(zip(("user", "passwd", "tenant"), parse_creds(fuel.creds)))
        fuel_conn = KeystoneAuth(fuel.url, creds)

        cluster_id = get_cluster_id(fuel_conn, fuel.openstack_env)
        cluster = reflect_cluster(fuel_conn, cluster_id)

        if ctx.fuel_version is None:
            ctx.fuel_version = FuelInfo(fuel_conn).get_version()
            ctx.storage.put(ctx.fuel_version, "fuel_version")

            logger.info("Found FUEL {0}".format(".".join(map(str, ctx.fuel_version))))
            openrc = cluster.get_openrc()

            if openrc:
                auth_url = cast(str, openrc['os_auth_url'])
                if ctx.fuel_version >= [8, 0] and auth_url.startswith("https://"):
                    logger.warning("Fixing FUEL 8.0 AUTH url - replace https://->http://")
                    auth_url = auth_url.replace("https", "http", 1)

                os_creds = OSCreds(name=cast(str, openrc['username']),
                                   passwd=cast(str, openrc['password']),
                                   tenant=cast(str, openrc['tenant_name']),
                                   auth_url=cast(str, auth_url),
                                   insecure=cast(bool, openrc['insecure']))

                ctx.fuel_openstack_creds = os_creds
            else:
                ctx.fuel_openstack_creds = None

            ctx.storage.put(list(ctx.fuel_openstack_creds), "fuel_os_creds")

        if metadata_only:
            logger.debug("Skip FUEL nodes  discovery due to discovery settings")
            return

        try:
            fuel_rpc = setup_rpc(connect(fuel_node_info),
                                 ctx.rpc_code,
                                 ctx.default_rpc_plugins,
                                 log_level=ctx.config.rpc_log_level)
        except AuthenticationException:
            msg = "FUEL nodes discovery failed - wrong FUEL master SSH credentials"
            if ignore_errors:
                raise StopTestError(msg)
            logger.warning(msg)
            return
        except Exception as exc:
            if ignore_errors:
                logger.exception("While connection to FUEL")
                raise StopTestError("Failed to connect to FUEL")
            logger.warning("Failed to connect to FUEL - %s", exc)
            return

        logger.debug("Downloading FUEL node ssh master key")
        fuel_key = fuel_rpc.get_file_content('/root/.ssh/id_rsa')
        network = 'fuelweb_admin' if ctx.fuel_version >= [6, 0] else 'admin'

        count = 0
        for count, fuel_node in enumerate(list(cluster.get_nodes())):
            ip = str(fuel_node.get_ip(network))
            ctx.merge_node(ConnCreds(to_ip(ip), "root", key=fuel_key), set(fuel_node.get_roles()))

        logger.debug("Found {} FUEL nodes for env {}".format(count, fuel.openstack_env))
