#!/usr/bin/env python3

import argparse
import logging
import os
import sys

import gi
gi.require_version('RwcalYang', '1.0')
gi.require_version('RwCal', '1.0')
gi.require_version('RwLog', '1.0')

import rift.cal.server as cal_server
import rift.cal.client as cal_client
import rift.cal.utils as cal_utils
import rift.rwcal.cloudsim.lxc as lxc
import rift.rwcal.cloudsim.lvm as lvm
import rift.rwcal.cloudsim.shell as shell

from prettytable import PrettyTable


START_PARSER = "start"
STOP_PARSER = "stop"
CLEAN_PARSER = "clean"
FCLEAN_PARSER = "force-clean"
IMAGE_PARSER = "image-create"
STATUS_PARSER = "status"


class CloudsimOperations(cal_utils.CloudSimCalMixin):
    def __init__(self, args):
        super().__init__()
        self.log = cal_utils.Logger(
                    daemon_mode=False,
                    log_name="Parser",
                    log_level=logging.getLevelName(args.log_level)).logger

        self.args = args
        self.operations = cal_server.CloudsimServerOperations(self.log)
        self.client = cal_client.CloudsimClient(self.log)
        self._cal, self._account = None, None

    @property
    def log_file(self):
        return cal_utils.Logger.LOG_FILE

    @cal_utils.check_and_create_bridge
    def start_server(self):
        self.operations.start_server(foreground=self.args.foreground)

    @cal_utils.check_and_create_bridge
    def stop_server(self):
        self.operations.stop_server()

    @cal_utils.check_and_create_bridge
    def clean_resources(self):
        """Clean all resource using rest APIs. """
        self.operations.clean_server(images=self.args.all)

    @cal_utils.check_and_create_bridge
    def upload_image(self):
        """Onboard image to cloudsim server."""
        self.client.upload_image(self.args.location, name=self.args.name)

    def force_clean_resources(self):
        """Force clean up all resource. """
        self.log.info("Cleaning up logs")
        shell.command("rm -f {}".format(self.log_file))

        self.log.info("Cleaning up PID file")
        shell.command("rm -f {}".format(self.operations.PID_FILE))

        try:
            self.log.info("Purging LXC resources")
            for container in lxc.containers():
                lxc.stop(container)

            for container in lxc.containers():
                lxc.destroy(container)

            lvm.destroy('rift')

        except shell.ProcessError:
            self.log.exception("Unable to purge resources. Trying a force clean now.")
            lxc.force_clean()

    @cal_utils.check_and_create_bridge
    def show_status(self):

        cld_tbl = PrettyTable(['PID', 'Status', 'Log file'])

        pid = self.operations.pid
        if pid:
            cld_tbl.add_row([pid, "RUNNING", self.log_file])
        else:
            cld_tbl.add_row(["-", "STOPPED", self.log_file])

        print ("Cloudsim server:")
        print (cld_tbl)

        if not pid:
            return

        # Images
        img_tbl = PrettyTable(['ID', 'Name', 'Format'])
        vlink_tbl = PrettyTable([
                'ID', 'Name', 'Bridge Name', 'State', 'Subnet', 'Ports', "IPs"])
        vdu_tbl = PrettyTable([
            'ID', 'Name', 'LXC Name', 'IP', 'State', 'Ports', "VLink ID"])


        images = self.client.images
        if images:
            for image in images:
                img_tbl.add_row([image.id, image.name, image.disk_format])

            print ("Images:")
            print (img_tbl)

        vlinks = self.client.vlinks
        if vlinks:
            for vlink in vlinks:

                ports, ips = [], []
                for cp in vlink.connection_points:
                    ports.append("{} ({})".format(cp.name, cp.connection_point_id))
                    ips.append(cp.ip_address)

                vlink_tbl.add_row([
                    vlink.virtual_link_id,
                    vlink.name,
                    vlink.name[:15],
                    vlink.state,
                    vlink.subnet,
                    "\n".join(ports),
                    "\n".join(ips)])

            print ("Vlink:")
            print (vlink_tbl)


        lxc_to_ip = lxc.ls_info()
        def get_lxc_name(ip):
            for lxc_name, ips in lxc_to_ip.items():
                if str(ip) in ips:
                    return lxc_name

            return ""

        vdus = self.client.vdus
        if vdus:
            for vdu in vdus:
                ports, links = [], []
                for cp in vdu.connection_points:
                    ports.append("{} ({})".format(cp.name, cp.ip_address))
                    links.append(cp.virtual_link_id)

                vdu_tbl.add_row([
                    vdu.vdu_id, vdu.name, get_lxc_name(vdu.public_ip), vdu.public_ip,
                    vdu.state, "\n".join(ports), "\n".join(links)])

            print ("VDU:")
            print (vdu_tbl)


def parse(arguments):
    parser = argparse.ArgumentParser(description=__doc__,
                                    formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument(
            '--log-level', '-l',
            default="WARNING",
            type=str,
            choices=["INFO", "DEBUG", "WARNING", "ERROR"],
            help="Set log level, defaults to warning and above.")

    subparsers = parser.add_subparsers()

    start_parser = subparsers.add_parser(START_PARSER, help="Start the server")
    start_parser.add_argument(
            '--foreground', "-f",
            help="Run the server in the foreground. The logs are sent to console.",
            default=False,
            action="store_true")
    start_parser.set_defaults(which=START_PARSER)

    stop_parser = subparsers.add_parser(STOP_PARSER, help="Stop the server")
    stop_parser.set_defaults(which=STOP_PARSER)

    clean_parser = subparsers.add_parser(
            CLEAN_PARSER,
            help="Clean LXC resources. By default all resources except " + \
                 "images are cleared.")
    clean_parser.add_argument(
            '--all', '-a', 
            help="Cleans up all resources including images",
            default=False,
            action="store_true")
    clean_parser.set_defaults(which=CLEAN_PARSER)

    fclean_parser = subparsers.add_parser(
            FCLEAN_PARSER,
            help="Force clean all lxc resources")
    fclean_parser.set_defaults(which=FCLEAN_PARSER)

    image_parser = subparsers.add_parser(IMAGE_PARSER, help="Upload images")
    image_parser.add_argument(
            '--name', '-n',
            help="(Optional) Name of the image")
    image_parser.add_argument(
            '--location', '-l',
            help="Image location. If name is not specified the basename of " + \
                 "the image path is used.",
            required=True)
    image_parser.set_defaults(which=IMAGE_PARSER)

    show_parser = subparsers.add_parser(
            STATUS_PARSER,
            help="Shows the current status of LXC")
    show_parser.set_defaults(which=STATUS_PARSER)

    args = parser.parse_args(arguments)

    return args


def main(args):

    args = parse(args)

    operations = CloudsimOperations(args)

    if args.which == START_PARSER:
        operations.start_server()
    elif args.which == STOP_PARSER:
        operations.stop_server()
    elif args.which == FCLEAN_PARSER:
        operations.force_clean_resources()
    elif args.which == CLEAN_PARSER:
        operations.clean_resources()
    elif args.which == IMAGE_PARSER:
        operations.upload_image()
    elif args.which == STATUS_PARSER:
        operations.show_status()


if __name__ == "__main__":
    main(sys.argv[1:])
