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

'''
CloudControl CLI class
'''

import os, os.path
import sys
import socket
import ssl
import threading
import cccli
from cccli import printer, command
from cccli.clierror import *
from sjrpc.client import SimpleRpcClient
from sjrpc.utils import RpcHandler, pure, threadless, ConnectionProxy

import re
import readline

class Cli(object):

    def __init__(self, settings, alias, args):
        self._settings = settings
        self._alias = alias
        self._interactive = sys.stderr.isatty() and sys.stdin.isatty()
        self._prompt = "> "
        self._commands = args
        self._rpc = None

    def start(self):
        '''Start a CLI'''
        # Connecting
        self._connect()
        # authentifications
        self._auth()
        # run parsing args
        if len(self._commands) > 0:
            for c in self._commands:
                self._parse(c)
        elif self._interactive:
            self._interactive_parser()
        else:
            self._parser()

    def _connect(self):
        printer.debug("Connecting...")
        rpcc = SimpleRpcClient.from_addr(self._settings["server"],
                                        self._settings["port"],
                                        enable_ssl=True
                                        )
        # FIXME: wait sjrpc v5 with on_disconnect usable
        rpcc.start(daemonize=True)
        self._rpc = ConnectionProxy(rpcc)

    def _auth(self):
        printer.debug("Authenticating...")
        if self._rpc.authentify(self._settings["login"], self._settings["pass"]):
            printer.debug("Authenticated.")
        else:
            printer.fatal("Autentification failed!")

    def _interactive_parser(self):
        '''Interactive shell parser'''
        # init readline

        while True:
            try:
                line = raw_input(self._prompt)
                self._parse_line(line)
            except BadCommand, e:
                printer.error("No such command: %s"%e[0])
            except EOFError:
                printer.out("")
                break
            except SystemExit:
                break
            except KeyboardInterrupt:
                printer.out("")
            except Exception, e:
                printer.error(e)
                if cccli.debug:
                    raise
                else:
                    printer.error("This is a not expected error, please report it!")
        try:
            pass
            #readline.write_history_file(self._settings["histfile"])
        except IOError:
            pass
        printer.out("Tcho!")

    def _parser(self):
        '''Non interactive parser'''
        while True:
            line = raw_input(self._prompt)
            self._parse_line(line)

    def _parse_line(self, line):
        '''Parse a line (more than one command)'''
        for cmd in line.split(";"):
            if (cmd.strip() == "" or cmd[0] == "#"):
                continue
            elif (cmd[0] == "!"):
                p = subprocess.Popen(cmd[1:], close_fds=True, shell=True)
                p.wait()
                ret = p.returncode
            elif (cmd[0] == "?"):
                command.Command("help").call()
            else:
                argv = self._lex_argv(cmd)
                command.Command(argv, self._rpc).call()

    def _lex_argv(self, string):
        return string.split(" ")