#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
from sys import stdout, stderr
from getpass import getpass
import re
import urllib2
import json

from temboardagent.options import agentRegisterOptions
from temboardagent.errors import (
    ConfigurationError,
    HTTPError,
)
from temboardagent.types import T_PASSWORD, T_USERNAME
from temboardagent.tools import validate_parameters
from temboardagent.httpsclient import https_request
from temboardagent.configuration import LazyConfiguration


def ask_password():
    try:
        raw_pass = os.environ['TEMBOARD_UI_PASSWORD']
    except KeyError:
        raw_pass = getpass(" Password: ")

    try:
        password = raw_pass
        validate_parameters({'password': password},
                            [('password', T_PASSWORD, False)])
    except HTTPError:
        stdout.write("Invalid password.\n")
        return ask_password()
    return password


def ask_username():
    try:
        raw_username = os.environ['TEMBOARD_UI_USER']
    except KeyError:
        raw_username = raw_input(" Username: ")

    try:
        username = raw_username
        validate_parameters({'username': username},
                            [('username', T_USERNAME, False)])
    except HTTPError:
        stdout.write("Invalid username.\n")
        return ask_username()
    return username


def main():
    """
    Main function.
    """
    # Instanciate a new CLI options parser.
    optparser = agentRegisterOptions(
                    usage="usage: %prog [options] <https-temboard-ui-address>",
                    add_help_option=False,
                    description="Register a couple PostgreSQL instance/agent "
                                "to a Temboard UI.")
    (options, args) = optparser.parse_args()

    if options.help is True:
        print(optparser.format_help().strip())
        exit(0)
    if len(args) != 1:
        print("ERROR: One argument is required.\n")
        print(optparser.format_help().strip())
        exit(1)

    # Loading agent configuration file.
    config = LazyConfiguration(options.configfile)

    ui_address = args[0]
    # Load configuration from the configuration file.
    try:
        # Getting system/instance informations using agent's discovering API
        print("Getting system & PostgreSQL informations from the agent "
              "(https://%s:%s/discover) .." % (options.host, options.port))
        (code, content, cookies) = https_request(
                None,
                'GET',
                "https://%s:%s/discover" % (options.host, options.port),
                headers={
                    "Content-type": "application/json"
                })
        infos = json.loads(content)
        for k, v in infos.iteritems():
            print(" %s: %s" % (k, v))

        # Authentication done by the UI
        print("")
        print("Login at %s." % (ui_address))
        username = ask_username()
        password = ask_password()
        (code, content, cookies) = https_request(
                None,
                'POST',
                "%s/json/login" % (ui_address),
                headers={
                    "Content-type": "application/json"
                },
                data={'username': username, 'password': password})
        temboard_cookie = None
        for cookie in cookies.split("\n"):
            cookie_content = cookie.split(";")[0]
            if re.match(r'^temboard=.*$', cookie_content):
                temboard_cookie = cookie_content
                continue

        if options.groups:
            groups = [g for g in options.groups.split(',')]
        else:
            groups = None

        # POSTing new instance
        print("")
        print("Registering instance/agent to %s .." % (ui_address))
        (code, content, cookies) = https_request(
                None,
                'POST',
                "%s/json/register/instance" % (ui_address),
                headers={
                    "Content-type": "application/json",
                    "Cookie": temboard_cookie
                },
                data={
                    'hostname': infos['hostname'],
                    'agent_key': config.temboard['key'],
                    'agent_address': options.host,
                    'agent_port': config.temboard['port'],
                    'cpu': infos['cpu'],
                    'memory_size': infos['memory_size'],
                    'pg_port': infos['pg_port'],
                    'pg_data': infos['pg_data'],
                    'pg_version': infos['pg_version'],
                    'plugins': infos['plugins'],
                    'groups': groups
                })
        if code != 200:
            raise HTTPError(code, content)
        print("Done.")
    except (ConfigurationError, HTTPError, Exception) as e:
        if isinstance(e, urllib2.HTTPError):
            err = json.loads(e.read())
            stderr.write("FATAL: %s\n" % err['error'])
        else:
            stderr.write("FATAL: %s\n" % str(e))
        exit(1)


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt as e:
        stdout.write("\nExit..\n")
