#!/usr/bin/env python
#coding=utf8

'''
CloudControl CLI Binary
'''

import os, os.path
import sys
import optparse
import ConfigParser
import pprint
import re
import warnings
from xdg import BaseDirectory

import cccli
from cccli.cli import Cli
from cccli.printer import Printer
from cccli.exception import *

settings = {
    "port": "1984",
    "timeout": "30",
    "hsize": "100",
    "alias": "%s/alias"%BaseDirectory.save_config_path(cccli.canonical_name),
    "history": "%s/history"%BaseDirectory.save_data_path(cccli.canonical_name),
    }

try:
    # load a printer
    printer = Printer(False)

    # parse profile file and load default profile
    try:
        propath = "%s/profile"%BaseDirectory.save_config_path(cccli.canonical_name)
        fparser = ConfigParser.RawConfigParser()
        fparser.read(propath)
        if fparser.has_section("cli"):
            settings.update(fparser.items("cli"))
    except Exception:
        fparser = None

    # load "default profile" profile
    if "profile" in settings:
        if fparser is not None and fparser.has_section(settings["profile"]):
            settings.update(fparser.items(settings["profile"]))
        del settings["profile"]

    # parse env
    if "CC_SERVER" in os.environ:
        settings["server"] = os.environ["CC_SERVER"]
    if "CC_PORT" in os.environ:
        settings["port"] = os.environ["CC_PORT"]
    if "CC_LOGIN" in os.environ:
        settings["login"] = os.environ["CC_LOGIN"]
    if "CC_PASS" in os.environ:
        settings["pass"] = os.environ["CC_PASS"]
    if "CC_DEBUG" in os.environ:
        settings["debug"] = "True"

    # load env profile
    if "CC_PROFILE" in os.environ:
        if fparser is not None and fparser.has_section(os.environ["CC_PROFILE"]):
            settings.update(fparser.items(os.environ["CC_PROFILE"]))

    # Parse line argument
    oparser = optparse.OptionParser(usage="usage: %prog [options] [commands]",
                                    version=cccli.version)
    oparser.add_option("-d", "--debug", action="store_true",dest="debug",
                       help="Debug mode")
    oparser.add_option("-l", "--login",action="store",dest="login",
                       help="Server login")
    oparser.add_option("-H", "--hostname",action="store",dest="server",
                       help="Server hostname")
    oparser.add_option("-P", "--port",action="store",dest="port",
                       help="Server port")
    oparser.add_option("-t", "--timeout",action="store",dest="timeout",
                       help="Connection timeout")
    oparser.add_option("-p", "--profile",action="store",dest="profile",
                       help="Profile name")
    oparser.add_option("--history-file",action="store",dest="history",
                       help="History file")
    oparser.add_option("--history-size",action="store",dest="hsize",
                       help="History max entry count")
    (options, args) = oparser.parse_args()

    # options handling
    for i in [ x.dest for x in oparser.option_list if x.dest ]:
        if hasattr(options, i):
            o = getattr(options, i)
            if o:
                settings[i] = o

    # load argline profile
    if "profile" in settings:
        if fparser is not None and fparser.has_section(settings["profile"]):
            settings.update(fparser.items(settings["profile"]))
        del settings["profile"]

    # debug stuff
    if "debug" in settings:
        cccli.debug = bool(settings["debug"])
    else:
        warnings.filterwarnings("ignore")
    printer.debug("Debugging on")

    # checking server name
    if "server" not in settings:
        raise BadArgument("No server address")

    # check int values
    for i in "port", "timeout", "hsize":
        try:
            settings[i] = int(settings[i])
        except:
            raise BadArgument("Invalid %s number"%i)
    # check login
    if "login" not in settings:
        printer.setinteractive()
        settings["login"] = printer.ask("Login: ")

    # check password
    if "pass" not in settings:
        printer.setinteractive()
        settings["pass"] = printer.getpass("Password: ")

    # print settings
    printer.debug("Settings: %s"%settings)

    # start cli
    cli = Cli(settings)
    cli.start(" ".join(args))
except BadArgument as e:
    printer.error("Bad Argument: %s"%str(e))
    oparser.print_help()
except KeyboardInterrupt:
    exit(1)
except cliError as e:
    printer.error("cliError: %s"%str(e))
except Exception as e:
    if cccli.debug:
        printer.fatal("%s: %s"%(type(e), str(e)), quit=False)
        raise
    printer.warn("This is a not expected error, please report it!")
    printer.fatal(str(e))
