import os.path
import logging

from . import ceph
from . import fuel
from . import openstack
from wally.utils import parse_creds


logger = logging.getLogger("wally.discover")


openrc_templ = """#!/bin/sh
export LC_ALL=C
export OS_NO_CACHE='true'
export OS_TENANT_NAME='{tenant}'
export OS_USERNAME='{name}'
export OS_PASSWORD='{passwd}'
export OS_AUTH_URL='{auth_url}'
export OS_AUTH_STRATEGY='keystone'
export OS_REGION_NAME='RegionOne'
export CINDER_ENDPOINT_TYPE='publicURL'
export GLANCE_ENDPOINT_TYPE='publicURL'
export KEYSTONE_ENDPOINT_TYPE='publicURL'
export NOVA_ENDPOINT_TYPE='publicURL'
export NEUTRON_ENDPOINT_TYPE='publicURL'
"""


def discover(ctx, discover, clusters_info, var_dir, discover_nodes=True):
    nodes_to_run = []
    clean_data = None
    ctx.fuel_openstack_creds = None

    for cluster in discover:
        if cluster == "openstack" and not discover_nodes:
            logger.warning("Skip openstack cluster discovery")
        elif cluster == "openstack" and discover_nodes:
            cluster_info = clusters_info["openstack"]
            conn = cluster_info['connection']
            user, passwd, tenant = parse_creds(conn['creds'])

            auth_data = dict(
                auth_url=conn['auth_url'],
                username=user,
                api_key=passwd,
                project_id=tenant)

            if not conn:
                logger.error("No connection provided for %s. Skipping"
                             % cluster)
                continue

            logger.debug("Discovering openstack nodes "
                         "with connection details: %r" %
                         conn)

            os_nodes = openstack.discover_openstack_nodes(auth_data,
                                                          cluster_info)
            nodes_to_run.extend(os_nodes)

        elif cluster == "fuel" or cluster == "fuel_openrc_only":
            if cluster == "fuel_openrc_only":
                discover_nodes = False

            res = fuel.discover_fuel_nodes(clusters_info['fuel'],
                                           var_dir,
                                           discover_nodes)
            nodes, clean_data, openrc_dict = res

            if openrc_dict is None:
                ctx.fuel_openstack_creds = None
            else:
                ctx.fuel_openstack_creds = {
                    'name': openrc_dict['username'],
                    'passwd': openrc_dict['password'],
                    'tenant': openrc_dict['tenant_name'],
                    'auth_url': openrc_dict['os_auth_url'],
                    'insecure': openrc_dict.get('insecure', False)}

            env_name = clusters_info['fuel']['openstack_env']
            env_f_name = env_name
            for char in "-+ {}()[]":
                env_f_name = env_f_name.replace(char, '_')

            fuel_openrc_fname = os.path.join(var_dir,
                                             env_f_name + "_openrc")

            if ctx.fuel_openstack_creds is not None:
                with open(fuel_openrc_fname, "w") as fd:
                    fd.write(openrc_templ.format(**ctx.fuel_openstack_creds))
                    msg = "Openrc for cluster {0} saves into {1}"
                    logger.info(msg.format(env_name, fuel_openrc_fname))
            nodes_to_run.extend(nodes)

        elif cluster == "ceph":
            if discover_nodes:
                cluster_info = clusters_info["ceph"]
                nodes_to_run.extend(ceph.discover_ceph_nodes(cluster_info))
            else:
                logger.warning("Skip ceph cluster discovery")
        else:
            msg_templ = "Unknown cluster type in 'discover' parameter: {0!r}"
            raise ValueError(msg_templ.format(cluster))

    return nodes_to_run
