#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Main program of the Client written for CIRCLE Cloud.
The Client job is to help the ease of use of the cloud system.
"""

from os import environ
import argparse
import subprocess
import logging
from logging.handlers import SysLogHandler

logformat='%(name)s: %(levelname)s %(message)s'
logging.basicConfig(format=logformat)
logger = logging.getLogger("circle_client")
logformatter = logging.Formatter(
        fmt=logformat
)
loghandler = SysLogHandler(
     facility=SysLogHandler.LOG_DAEMON,
     address='/dev/log'
)
loghandler.setFormatter(logformatter)
logger.addHandler(loghandler)

def remina_password(pw):
    args = ["remmina", "--encrypt-password", "--no-tray-icon"]
    process = subprocess.run(args, input=pw, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, encoding="utf-8", timeout=5)
    b = process.stdout.find("Encrypted password:")
    process.stdout[b::].split()
    return process.stdout[198::].split()[2]

def connect(vm):
    """
    Handles to connection to the Virtual Machines from the local
    machine

    Keyword arguments:
    vm.protocol -- SSH, NX and RDP possible
    vm.host     -- Address of the Virtual Computer
    vm.port     -- The port where we can access the Virtual Computer
    vm.user     -- Username used for the connection
    vm.password -- Password used for the connection
    """
    command = None
    if vm.protocol == "SSH":
        command = ("sshpass -p %(password)s ssh -p %(port)s"
                   " -o StrictHostKeyChecking=no %(user)s@%(host)s" % {
                       'password': vm.password,
                       'port': vm.port,
                       'user': vm.user,
                       'host': vm.host,
                   })
    elif vm.protocol in ("NX", "RDP"):
        password = remina_password(vm.password)
        if vm.protocol == "RDP":
           command = ("remmina --no-tray-icon" 
               " -c rdp://%(user)s:%(password)s@%(host)s:%(port)s" % {
                       'user': vm.user,
                       'password': password,
                       'host': vm.host,
                       'port': vm.port,
                   })
        else:
           command = ("remmina --no-tray-icon" 
               " -c rdp://%(user)s:%(password)s@%(host)s:%(port)s" % {
                       'user': vm.user,
                       'password': password,
                       'host': vm.host,
                       'port': vm.port,
                   })
    logger.debug("Running: s", command)
    subprocess.call(command, shell=True)


class Struct:
    """
    A struct used for parameter passing

    Keyword arguments:
    state    -- State of the Virtual Computer (running, etc..)
    protocol -- SSH, NX and RDP possible
    host     -- Address of the Virtual Computer
    port     -- The port where we can access the Virtual Computer
    user     -- Username used for the connection
    password -- Password used for the connection
    """
    pass


def parse_arguments():
    """
    Argument parser, based on the argparse module

    Keyword arguments:
    @return args -- arguments given by console
    """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "uri", type=str, help="Specific schema handler", nargs='?',
        default=None)
    parser.add_argument(
        "-l", "--loglevel",
        help="The level of logging severity", type=str,
        choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
        default=None)
    args = parser.parse_args()
    return args

def main():
    """
    Main program
    """
    args = parse_arguments()
    if args.loglevel == None:
        level = environ.get('LOGLEVEL', 'INFO')
    else:
        level = args.loglevel
    logger.setLevel(level)
    logger.info("Started")
    try:
        if args.uri is not None:
            vm = Struct()
            x, vm.protocol, vm.user, vm.password, vm.host, vm.port = \
                args.uri.split(':', 5)
            logger.debug(("Received the following URI: %(handler)s:"
                         "%(protocol)s:%(user)s:password:%(host)s:%(port)s" % {
                             'handler': x,
                             'protocol': vm.protocol,
                             'user': vm.user,
                             'host': vm.host,
                             'port': vm.port
                         }))
            vm.protocol = vm.protocol.upper()
        else:
           logger.critical("Client did not receive an URI which would be "
                            "necessary to continue") 
        connect(vm)
    except Exception as e:
        logger.exception("An exception %s was raised before connect methods"
                         "could be invoked", e)


if __name__ == "__main__":
    main()
