#!/usr/bin/env python
# -*- 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.
"""

import platform
import argparse
try:
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
except ImportError:
    pass


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("-u", "--username", type=str)
    parser.add_argument("-p", "--password", type=str)
    parser.add_argument(
        "-d", "--driver",
        help="Select webdriver. Aside from Firefox, you have to install "
        + "first the proper driver.", type=str,
        choices=['firefox', 'chrome', 'ie', 'opera'],
        default="firefox")
    args = parser.parse_args()
    return args


class Browser:
    """
    Browser initialisation

    Keyword arguments:
    @param args  -- args.driver tells us which installed browser
                    we want to use with selenium.
    """
    def __init__(self, args):
        self.args = args
        if args.driver == "firefox":
            self.driver = webdriver.Firefox()
        elif args.driver == "chrome":
            self.driver = webdriver.Chrome()
        elif args.driver == "ie":
            self.driver = webdriver.Ie()
        elif args.driver == "opera":
            self.driver = webdriver.Opera()
        self.driver.implicitly_wait(10)

    def login(self):
        """
        Eduid login based on the given console arguments
        """
        driver = self.driver
        args = self.args
        if args.username is not None:
            driver.find_element_by_name("j_username").clear()
            driver.find_element_by_name("j_username").send_keys(args.username)
        if args.password is not None:
            driver.find_element_by_name("j_password").clear()
            driver.find_element_by_name("j_password").send_keys(args.password)
        if args.username is not None and args.password is not None:
            driver.find_element_by_css_selector(
                "input[type='submit']").click()

    def main(self):
        """
        Use of the https://cloud.bme.hu/

        Keyword arguments:
        @return vm   -- Necessarily parameters to connect
                        to the Virtual Machine
        """
        vm = Struct()
        driver = self.driver
        driver.maximize_window()
        driver.get("https://cloud.bme.hu/")
        # driver.find_element_by_css_selector("a[href*='/login/']").click()
        # self.login()
        vm.state, vm.protocol = "", "NONE"
        try:
            while vm.state.upper()[:3] not in ("FUT", "RUN"):
                WebDriverWait(driver, 7200).until(
                    EC.presence_of_element_located((
                        By.CSS_SELECTOR,
                        "#vm-details-pw-eye.fa.fa-eye-slash")))
                vm.state = driver.find_element_by_css_selector(
                    "#vm-details-state > span").text
            # cl: connection string converted to list
            cl = driver.find_element_by_css_selector(
                "#vm-details-connection-string").get_attribute(
                    "value").split()
            if cl[0] == "sshpass":
                vm.protocol = "SSH"
                vm.user, vm.host = cl[6].split("@")
                vm.password, vm.port = cl[2], cl[8]
            elif cl[0] == "rdesktop":
                vm.protocol = "RDP"
                vm.host, vm.port = cl[1].split(":")
                vm.user, vm.password = cl[3], cl[5]
            driver.find_element_by_css_selector("a[href*='/logout/']").click()
        except:
            print "Browser session timed out!"
            raise
        return vm


def main():
    """
    Main program
    """
    try:
        args = parse_arguments()
        if args.uri is not None:
            vm = Struct()
            vm.protocol, vm.user, vm.password, vm.host, vm.port = \
                args.uri.split(':', 4)
            vm.protocol = vm.protocol.upper()
            vm.state = "RUN"
        else:
            browser = Browser(args)
            vm = browser.main()
            browser.driver.quit()
        if platform.system() == "Linux":
            from cloud_connect_from_linux import connect
        elif platform.system() == "Windows":
            from cloud_connect_from_windows import connect
        if vm.state.upper()[:3] in ("FUT", "RUN"):
            connect(vm)
    except:
        print "Unknown error occurred! Please contact the developers!"


if __name__ == "__main__":
    main()
