#!/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),
    "expert": "%s/expert"%BaseDirectory.save_data_path(cccli.canonical_name),
    }

try:
    # Early debug loading
    if "CC_DEBUG" in os.environ:
        settings["debug"] = "True"
        cccli.debug = True

    # load a printer
    printer = Printer(False)

    # 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()

    # try loading profiles
    try:
        # parse profile file
        propath = "%s/profile"%BaseDirectory.save_config_path(cccli.canonical_name)
        fparser = ConfigParser.RawConfigParser()
        fparser.read(propath)
        # load default profile
        if fparser.has_section("cli"):
            settings.update(fparser.items("cli"))
        # load next profile from cli profile
        if "profile" in settings:
            if fparser.has_section(settings["profile"]):
                settings.update(fparser.items(settings["profile"]))
                del settings["profile"]
            else:
                printer.warn("Unable to load profile %s"%settings["profile"])
        # load env profile
        if "CC_PROFILE" in os.environ:
            if fparser.has_section(os.environ["CC_PROFILE"]):
                settings.update(fparser.items(os.environ["CC_PROFILE"]))
            else:
                printer.warn("Unable to load profile %s"%os.environ["CC_PROFILE"])
        # load argline profile
        if options.profile:
            if fparser.has_section(options.profile):
                settings.update(fparser.items(options.profile))
            else:
                printer.warn("Unable to load profile %s"%option.profile)
    except Exception as e:
        if cccli.debug:
            raise
        pass

    # Load environment variables
    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"]

    # Load command line options
    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

    # 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))
