import os
import re
import sys
import socket
import logging
from urlparse import urlparse

import yaml
from wally.fuel_rest_api import (KeystoneAuth, get_cluster_id,
                                 reflect_cluster, FuelInfo)
from wally.utils import parse_creds
from wally.ssh_utils import run_over_ssh, connect

from .node import Node


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


def discover_fuel_nodes(fuel_data, var_dir, discover_nodes=True):
    username, tenant_name, password = parse_creds(fuel_data['creds'])
    creds = {"username": username,
             "tenant_name": tenant_name,
             "password": password}

    conn = KeystoneAuth(fuel_data['url'], creds, headers=None)

    cluster_id = get_cluster_id(conn, fuel_data['openstack_env'])
    cluster = reflect_cluster(conn, cluster_id)

    if not discover_nodes:
        logger.warning("Skip fuel cluster discovery")
        return ([], None, cluster.get_openrc())

    version = FuelInfo(conn).get_version()

    fuel_nodes = list(cluster.get_nodes())

    logger.debug("Found FUEL {0}".format(".".join(map(str, version))))

    network = 'fuelweb_admin' if version >= [6, 0] else 'admin'

    ssh_creds = fuel_data['ssh_creds']

    fuel_host = urlparse(fuel_data['url']).hostname
    fuel_ip = socket.gethostbyname(fuel_host)
    ssh_conn = connect("{0}@@{1}".format(ssh_creds, fuel_host))

    fuel_ext_iface = get_external_interface(ssh_conn, fuel_ip)

    # TODO: keep ssh key in memory
    # http://stackoverflow.com/questions/11994139/how-to-include-the-private-key-in-paramiko-after-fetching-from-string
    fuel_key_file = os.path.join(var_dir, "fuel_master_node_id_rsa")
    download_master_key(ssh_conn, fuel_key_file)

    nodes = []
    ports = range(BASE_PF_PORT, BASE_PF_PORT + len(fuel_nodes))
    ips_ports = []

    for fuel_node, port in zip(fuel_nodes, ports):
        ip = fuel_node.get_ip(network)
        forward_ssh_port(ssh_conn, fuel_ext_iface, port, ip)

        conn_url = "ssh://root@{0}:{1}:{2}".format(fuel_host,
                                                   port,
                                                   fuel_key_file)
        node = Node(conn_url, fuel_node['roles'])
        node.monitor_url = None
        nodes.append(node)
        ips_ports.append((ip, port))

    logger.debug("Found %s fuel nodes for env %r" %
                 (len(nodes), fuel_data['openstack_env']))

    # return ([],
    #         (ssh_conn, fuel_ext_iface, ips_ports),
    #         cluster.get_openrc())

    return (nodes,
            (ssh_conn, fuel_ext_iface, ips_ports),
            cluster.get_openrc())


def download_master_key(conn, dest):
    # download master key
    sftp = conn.open_sftp()
    sftp.get('/root/.ssh/id_rsa', dest)
    os.chmod(dest, 0o400)
    sftp.close()

    logger.debug("Fuel master key stored in {0}".format(dest))


def get_external_interface(conn, ip):
    data = run_over_ssh(conn, "ip a", node='fuel-master')
    curr_iface = None
    for line in data.split("\n"):

        match1 = re.match(r"\d+:\s+(?P<name>.*?):\s\<", line)
        if match1 is not None:
            curr_iface = match1.group('name')

        match2 = re.match(r"\s+inet\s+(?P<ip>[0-9.]+)/", line)
        if match2 is not None:
            if match2.group('ip') == ip:
                assert curr_iface is not None
                return curr_iface
    raise KeyError("Can't found interface for ip {0}".format(ip))


def forward_ssh_port(conn, iface, new_port, ip, clean=False):
    mode = "-D" if clean is True else "-A"
    cmd = "iptables -t nat {mode} PREROUTING -p tcp " + \
          "-i {iface} --dport {port} -j DNAT --to {ip}:22"
    run_over_ssh(conn,
                 cmd.format(iface=iface, port=new_port, ip=ip, mode=mode),
                 node='fuel-master')


def clean_fuel_port_forwarding(clean_data):
    if clean_data is None:
        return

    conn, iface, ips_ports = clean_data
    for ip, port in ips_ports:
        forward_ssh_port(conn, iface, port, ip, clean=True)


def main(argv):
    fuel_data = yaml.load(open(sys.argv[1]).read())['clouds']['fuel']
    nodes, to_clean, openrc = discover_fuel_nodes(fuel_data, '/tmp')

    print nodes
    print openrc
    print "Ready to test"

    sys.stdin.readline()

    clean_fuel_port_forwarding(to_clean)

    return 0


if __name__ == "__main__":
    main(sys.argv[1:])
