#! /usr/bin/env python
# -*- Mode: python; py-indent-offset: 4; tab-width: 8; -*-

"""
onoscli : ONOS-specific Command Line Interface

Usage:
    # Running the CLI in interactive mode:
    $ ./onoscli

    # Running multiple CLI commands in batch mode
    $ cat commands.txt | ./onoscli

    # Running a single command from the system command-line
    $ ./onoscli -c show switch

    # Run the following command for additional help
    $ ./onoscli -h
"""

#
# INSTALLATION NOTES: MUST install Python cmd2 module. E.g., on Ubuntu:
#    sudo apt-get install python-cmd2
# On older Ubuntu installations (e.g., Ubuntu-12.04 or Ubuntu-13.04), install
# also:
#    sudo apt-get install python-pyparsing
#

#
# ADDING A NEW CLI COMMAND:
#  1. Add the appropriate Command entry (or entries) inside array
#     OnosCli.init_commands.
#     See the comments for init_commands for details.
#  2. Add the appropriate callback (inside class OnosCli) for the CLI command
#
#

import sys
import argparse
import json
from optparse import make_option
import urllib2
from urllib2 import URLError, HTTPError
import cmd2
from cmd2 import Cmd
from cmd2 import options


class Command():
    "Command node. A hierarchy of nodes are organized in a command tree."

    def __init__(self, name, help, callback=None, add_parser_args=None):
        """name: a string with the full command name
           help: the help string for the command
           callback: the method to be called if the command is executed
           add_parser_args: the parser arguments to add to the command: a dictionary of argparse arguments"""
        # Normalize the name by removing extra spaces
        self.split_name = name.split()  # List of the words in the name
        self.name = ' '.join(self.split_name)   # Normalized name
        self.last_subname = self.split_name[-1] # Last word in the name
        self.parent_name = ' '.join(self.split_name[:-1]) # Name of parent command
        self.help = help                # THe help string
        self.callback = callback        # The command callback
        self.add_parser_args = add_parser_args  # Parser arguments to add
        self.parent = None              # The parent Command
        self.children = []              # The children Command entries


class OnosCli(Cmd):
    "The main ONOS CLI class"

    # Setup generic CLI fields
    intro = "Welcome to the ONOS CLI. Type help or ? to list commands.\n"
    prompt = "(onos) "
    settable = Cmd.settable + "prompt CLI prompt"

    # Setup ONOS-specific fields
    onos_ip = "127.0.0.1"
    settable = settable + "onos_ip ONOS IP address"
    onos_port = 8080
    settable = settable + "onos_port ONOS REST port number"
    output_format = "json"      # Valid values: json, text
    settable = settable + "output_format The output format: `text` or `json`"

    # Collection of commands sorted by the level in the CLI command hierarchy
    commands = []
    # Commands, parsers and subparsers keyed by the command name
    commands_dict = {}
    parsers_dict = {}
    subparsers_dict = {}

    def __init__(self):
        Cmd.__init__(self)

        #
        # An array of the ONOS-specific CLI commands.
        # Each entry is a Command instance, and must have at least
        # two arguments:
        #  * Command name as typed on the CLI. E.g.:
        #    "show intent"
        #  * Command help description. E.g.:
        #    "Show intents"
        #
        # Executable commands should have a third Command argument, which is
        # the name of the method to be called when the command is executed.
        # The method will be called with the (argparse) parsed arguments
        # for that command.
        #
        # If an executable command takes arguments, those should be described
        # in the Command's fourth argument. It is a list of pairs:
        #   [
        #    ("--argument-name1", dict(...)),
        #    ("--argument-name2", dict(...)),
        #    ...
        #   ]
        # where the first entry in the pair is the argument name, and the
        # second entry in the pair is a dictionary with argparse-specific
        # description of the argument.
        #
        init_commands = [
            Command("delete", "Delete command"),
            #
            Command("delete intent",
                    """Delete high-level intents
    Usage:
      delete intent --intent-id INTENT_ID  Delete a high-level intent
      delete intent --all                  Delete all high-level intents
    Arguments:
      --intent-id INTENT_ID    The Intent ID (an integer)
      --all                    Delete all high-level intents""",
                    self.delete_intent,
                    [
                    ("--intent-id", dict(required=False, type=int)),
                    ("--all", dict(required=False, action='store_true'))
                    ]
                    ),
            #
            Command("set", "Set command"),
            #
            Command("set intent",
                    """Set a high-level intent
    Usage:
      set intent <ARGS>
    Arguments:
      --intent-id INTENT_ID     The Intent ID (an integer) (REQUIRED)
      --src-dpid SRC_DPID       Source Switch DPID (REQUIRED)
      --src-port SRC_PORT       Source Switch Port (REQUIRED)
      --dst-dpid DST_DPID       Destination Switch DPID (REQUIRED)
      --dst-port DST_PORT       Destination Switch Port (REQUIRED)
      --match-src-mac MATCH_SRC_MAC Matching Source MAC Address (REQUIRED)
      --match-dst-mac MATCH_DST_MAC Matching Destination MAC Address (REQUIRED)""",
                    self.set_intent,
                    [
                    ("--intent-id", dict(required=True, type=int)),
                    ("--src-dpid", dict(required=True)),
                    ("--src-port", dict(required=True, type=int)),
                    ("--dst-dpid", dict(required=True)),
                    ("--dst-port", dict(required=True, type=int)),
                    ("--match-src-mac", dict(required=True)),
                    ("--match-dst-mac", dict(required=True))
                    ]),
            #
            Command("show", "Show command"),
            #
            Command("show host", "Show all hosts", self.show_host),
            #
            Command("show intent", "Show intents"),
            #
            Command("show intent high",
                    """Show all high-level intents
  show intent high --intent-id INTENT_ID    Show a high-level intent""",
                    self.show_intent_high,
                    [
                    ("--intent-id", dict(required=False, type=int))
                    ]
                    ),
            #
            Command("show intent low",
                    """Show all low-level intents
  show intent low  --intent-id INTENT_ID    Show a low-level intent""",
                    self.show_intent_low,
                    [
                    ("--intent-id", dict(required=False))
                    ]
                    ),
            #
            Command("show link", "Show all links", self.show_link),
            #
            Command("show metrics",
                    """Show all metrics
  show metrics --metric-id METRIC_ID        Show a metric""",
                    self.show_metrics,
                    [
                    ("--metric-id", dict(required=False, type=str)),
                    ]
                    ),
            #
            Command("show path", "Show a path"),
            #
            Command("show path shortest",
                    """Show a shortest path
    Usage:
      show path shortest --src-dpid SRC_DPID --dst-dpid DST_DPID
    Arguments:
      --src-dpid SRC_DPID       Source Switch DPID
      --dst-dpid DST_DPID       Destination Switch DPID""",
                    self.show_path_shortest,
                    [
                    ("--src-dpid", dict(required=True)),
                    ("--dst-dpid", dict(required=True))
                    ]),
            #
            Command("show switch", "Show all switches", self.show_switch),
            #
            Command("show topology", "Show network topology", self.show_topology)
        ]

        # Sort the commands by the level in the CLI command hierarchy
        self.commands = sorted(init_commands, key = lambda c: len(c.name.split()))

        # Create a dictionary with all commands: name -> Command
        for c in self.commands:
            self.commands_dict[c.name] = c

        # Create a tree with all commands
        for c in self.commands:
            if c.parent_name:
                pc = self.commands_dict[c.parent_name]
                pc.children.append(c)
                c.parent = pc

        # Create the parsers and the sub-parsers
        for c in self.commands:
            # Add a parser
            parser = None
            if c.parent is None:
                # Add a top-level parser
                parser = argparse.ArgumentParser(description=c.help,
                                                 prog=c.name,
                                                 add_help=False)
            else:
                # Add a parser from the parent's subparser
                parent_subparser = self.subparsers_dict[c.parent_name]
                parser = parent_subparser.add_parser(c.last_subname,
                                                     help=c.help,
                                                     add_help=False)
            self.parsers_dict[c.name] = parser
            # Add a sub-parser
            if c.children:
                subparser = parser.add_subparsers(help=c.help)
                self.subparsers_dict[c.name] = subparser
            # Setup the callback
            if c.callback is not None:
                parser.set_defaults(func=c.callback)
            # Init the argument parser
            if c.add_parser_args is not None:
                for a in c.add_parser_args:
                    (p1, p2) = a
                    parser.add_argument(p1, **p2)

    def delete_intent(self, args):
        "CLI command callback: delete intent"

        url = ""
        if args.all:
            # Delete all intents
            url = "http://%s:%s/wm/onos/intent/high" % (self.onos_ip, self.onos_port)
        else:
            if args.intent_id is None:
                print "*** Unknown syntax:"
                self.help_delete()
                return
            # Delete an intent
            url = "http://%s:%s/wm/onos/intent/high/%s" % (self.onos_ip, self.onos_port, args.intent_id)

        result = delete_json(url)
        # NOTE: No need to print the response
        # if len(result) != 0:
        #     self.print_json_result(result)

    def set_intent(self, args):
        "CLI command callback: set intent"

        intents = []
        oper = {}
        # Create the POST payload
        oper['intentId'] = args.intent_id
        oper['intentType'] = 'SHORTEST_PATH'    # XXX: Hardcoded
        oper['staticPath'] = False              # XXX: Hardcoded
        oper['srcSwitchDpid'] = args.src_dpid
        oper['srcSwitchPort'] = args.src_port
        oper['dstSwitchDpid'] = args.dst_dpid
        oper['dstSwitchPort'] = args.dst_port
        oper['matchSrcMac'] = args.match_src_mac
        oper['matchDstMac'] = args.match_dst_mac
        intents.append(oper)

        url = "http://%s:%s/wm/onos/intent/high" % (self.onos_ip, self.onos_port)
        result = post_json(url, intents)
        # NOTE: No need to print the response
        # if len(result) != 0:
        #     self.print_json_result(result)

    def show_host(self, args):
        "CLI command callback: show host"

        url = "http://%s:%s/wm/onos/topology/hosts" % (self.onos_ip, self.onos_port)
        result = get_json(url)
        self.print_json_result(result)

    def show_intent_high(self, args):
        "CLI command callback: show intent high"

        if args.intent_id is None:
            # Show all intents
            url = "http://%s:%s/wm/onos/intent/high" % (self.onos_ip, self.onos_port)
        else:
            # Show a single intent
            url = "http://%s:%s/wm/onos/intent/high/%s" % (self.onos_ip, self.onos_port, args.intent_id)

        result = get_json(url)
        self.print_json_result(result)

    def show_intent_low(self, args):
        "CLI command callback: show intent low"

        if args.intent_id is None:
            # Show all intents
            url = "http://%s:%s/wm/onos/intent/low" % (self.onos_ip, self.onos_port)
        else:
            # Show a single intent
            url = "http://%s:%s/wm/onos/intent/low/%s" % (self.onos_ip, self.onos_port, args.intent_id)

        result = get_json(url)
        self.print_json_result(result)

    def show_link(self, args):
        "CLI command callback: show link"

        url = "http://%s:%s/wm/onos/topology/links" % (self.onos_ip, self.onos_port)
        result = get_json(url)
        #
        if (self.output_format == "json"):
            self.print_json_result(result)
        else:
            # NOTE: The code below is for demo purpose only how to
            # decode and print the links in text format. It will be
            # reimplemented in the future.
            links = result
            print "# src_dpid src_port -> dst_dpid dst_port"
            for v in sorted(links, key=lambda x: x['src']['dpid']):
                src_dpid = str(v['src']['dpid'])
                src_port = str(v['src']['portNumber'])
                dst_dpid = str(v['dst']['dpid'])
                dst_port = str(v['dst']['portNumber'])
                self.print_result("%s %s -> %s %s" % (src_dpid, src_port, dst_dpid, dst_port))

    def show_metrics(self, args):
        "CLI command callback: show metrics"

        if args.metric_id is None:
            # Show all metrics
            url = "http://%s:%s/wm/onos/metrics" % (self.onos_ip, self.onos_port)
        else:
            # Show a single metric
            url = "http://%s:%s/wm/onos/metrics?ids=%s" % (self.onos_ip, self.onos_port, args.metric_id)

        result = get_json(url)
        self.print_json_result(result)

    def show_path_shortest(self, args):
        "CLI command callback: show path shortest"

        url = "http://%s:%s/wm/onos/intent/path/switch/%s/shortest-path/%s" % (self.onos_ip, self.onos_port, args.src_dpid, args.dst_dpid)
        result = get_json(url)
        #
        self.print_json_result(result)

    def show_switch(self, args):
        "CLI command callback: show switch"

        url = "http://%s:%s/wm/onos/topology/switches" % (self.onos_ip, self.onos_port)
        result = get_json(url)
        #
        self.print_json_result(result)

    def show_topology(self, args):
        "CLI command callback: show topology"

        url = "http://%s:%s/wm/onos/topology" % (self.onos_ip, self.onos_port)
        result = get_json(url)
        #
        self.print_json_result(result)

    #
    # Implement "delete" top-level command
    #
    def do_delete(self, arg):
        "Top-level 'delete' command"
        self.impl_do_command('delete', arg)
    def complete_delete(self, text, line, begidx, endidx):
        "Completion of top-level 'delete' command"
        return self.impl_complete_command('delete', text, line, begidx, endidx)
    def help_delete(self):
        "Help for top-level 'delete' command"
        self.impl_help_command('delete')

    #
    # Implement "set" top-level command
    #
    def do_set(self, arg):
        "Top-level 'set' command"
        self.impl_do_command('set', arg)
    def complete_set(self, text, line, begidx, endidx):
        "Completion of top-level 'set' command"
        return self.impl_complete_command('set', text, line, begidx, endidx)
    def help_set(self):
        "Help for top-level 'set' command"
        self.impl_help_command('set')

    #
    # Implement "show" top-level command
    #
    def do_show(self, arg):
        "Top-level 'show' command"
        self.impl_do_command('show', arg)
    def complete_show(self, text, line, begidx, endidx):
        "Completion of top-level 'show' command"
        return self.impl_complete_command('show', text, line, begidx, endidx)
    def help_show(self):
        "Help for top-level 'show' command"
        self.impl_help_command('show')

    #
    # Implement the "do_something" top-level command execution
    #
    def impl_do_command(self, root_name, arg):
        "Implementation of top-level 'do_something' command execution"
        parser = self.parsers_dict[root_name]
        parsed_args = parser.parse_args(arg.split())
        parsed_args.func(parsed_args)

    #
    # Implement the "complete_something" top-level command completion
    #
    def impl_complete_command(self, root_name, text, line, begidx, endidx):
        "Implementation of top-level 'complete_something' command completion"
        root_command = self.commands_dict[root_name]
        subtree_commands = self.collect_subtree_commands(root_command)

        #
        # Loop through the commands and add their portion
        # of the sub-name to the list of completions.
        #
        # NOTE: We add a command only if it has a callback.
        #
        completions = []
        for c in subtree_commands:
            if c.callback is None:
                continue
            name = c.split_name[len(root_command.split_name):]
            completions.append(' '.join(name))

        mline = line.partition(" ")[2]
        offs = len(mline) - len(text)
        return [s[offs:] for s in completions if s.startswith(mline)]

    #
    # Implement the "help_something" top-level command help
    #
    def impl_help_command(self, root_name):
        "Implementation of top-level 'help_something' command help"
        root_command = self.commands_dict[root_name]
        subtree_commands = self.collect_subtree_commands(root_command)

        #
        # Loop through the commands and print the help for each command.
        # NOTE: We add a command only if it has a callback.
        #
        print "Help for the `%s` command:" % (root_name)
        for c in subtree_commands:
            if c.callback is None:
                continue
            print "  {0:30}{1:30}".format(c.name, c.help)
            # if c.init_arg_parser is not None:
            #   parser = self.parsers_dict[c.name]
            #   parser.print_help()

    #
    # Traverse (depth-first) a subtree and return all nodes except the
    # root node.
    #
    def collect_subtree_commands(self, root_command):
        """Collect a subtree of commands.
           Traverses (depth-first) a subtree of commands and returns
           all nodes except the root node."""

        commands = []
        subtree_commands = []
        # Use depth-first to traverse the subtree
        for c in root_command.children:
            commands.append(c)
            subtree_commands = self.collect_subtree_commands(c)
            if len(subtree_commands):
                commands.extend(subtree_commands)
        return commands

    def log_debug(self, msg):
        """Log debug information.
        msg: the message to log
        Use the following CLI commands to enable/disable debugging:
          paramset debug true
          paramset debug false
        """
        if self.debug:
            print "%s" % (msg)

    def print_json_result(self, json_result):
        """Print JSON result."""
        if len(json_result) == 0:
            return
        result = json.dumps(json_result, indent=4)
        self.print_result(result)

    def print_result(self, result):
        """Print parsed result."""
        print "%s" % (result)

    #
    # Implementation of the "paramshow" CLI command.
    #
    # NOTE: The do_paramshow implementation below is copied from
    # the cmd2.do_show() implementation
    #
    @options([make_option('-l', '--long', action="store_true",
                 help="describe function of parameter")])
    def do_paramshow(self, arg, opts):
        '''Shows value of a parameter.'''
        param = arg.strip().lower()
        result = {}
        maxlen = 0
        for p in self.settable:
            if (not param) or p.startswith(param):
                result[p] = '%s: %s' % (p, str(getattr(self, p)))
                maxlen = max(maxlen, len(result[p]))
        if result:
            for p in sorted(result):
                if opts.long:
                    self.poutput('%s # %s' % (result[p].ljust(maxlen), self.settable[p]))
                else:
                    self.poutput(result[p])
        else:
            raise NotImplementedError("Parameter '%s' not supported (type 'show' for list of parameters)." % param)

    #
    # Implementation of the "paramset" CLI command.
    #
    #
    # NOTE: The do_paramset implementation below is copied from
    # the cmd2.do_set() implementation (with minor modifications).
    #
    def do_paramset(self, arg):
        '''
        Sets a cmd2 parameter.  Accepts abbreviated parameter names so long
        as there is no ambiguity.  Call without arguments for a list of
        settable parameters with their values.'''

        class NotSettableError(Exception):
            pass

        try:
            statement, paramName, val = arg.parsed.raw.split(None, 2)
            val = val.strip()
            paramName = paramName.strip().lower()
            if paramName not in self.settable:
                hits = [p for p in self.settable if p.startswith(paramName)]
                if len(hits) == 1:
                    paramName = hits[0]
                else:
                    return self.do_paramshow(paramName)
            currentVal = getattr(self, paramName)
            if (val[0] == val[-1]) and val[0] in ("'", '"'):
                val = val[1:-1]
            else:
                val = cmd2.cast(currentVal, val)
            setattr(self, paramName, val)
            self.stdout.write('%s - was: %s\nnow: %s\n' % (paramName, currentVal, val))
            if currentVal != val:
                try:
                    onchange_hook = getattr(self, '_onchange_%s' % paramName)
                    onchange_hook(old=currentVal, new=val)
                except AttributeError:
                    pass
        except (ValueError, AttributeError, NotSettableError) as exc:
            self.do_paramshow(arg)


def get_json(url):
    """Make a REST GET call and return the JSON result
       url: the URL to call"""

    parsed_result = []
    try:
        response = urllib2.urlopen(url)
        result = response.read()
        response.close()
        if len(result) != 0:
            parsed_result = json.loads(result)
    except HTTPError as exc:
        print "ERROR:"
        print "  REST GET URL: %s" % url
        # NOTE: exc.fp contains the object with the response payload
        error_payload = json.loads(exc.fp.read())
        print "  REST Error Code: %s" % (error_payload['code'])
        print "  REST Error Summary: %s" % (error_payload['summary'])
        print "  REST Error Description: %s" % (error_payload['formattedDescription'])
        print "  HTTP Error Code: %s" % exc.code
        print "  HTTP Error Reason: %s" % exc.reason
    except URLError as exc:
        print "ERROR:"
        print "  REST GET URL: %s" % url
        print "  URL Error Reason: %s" % exc.reason
    return parsed_result

def post_json(url, data):
    """Make a REST POST call and return the JSON result
       url: the URL to call
       data: the data to POST"""

    parsed_result = []
    data_json = json.dumps(data)
    try:
        request = urllib2.Request(url, data_json)
        request.add_header("Content-Type", "application/json")
        response = urllib2.urlopen(request)
        result = response.read()
        response.close()
        if len(result) != 0:
            parsed_result = json.loads(result)
    except HTTPError as exc:
        print "ERROR:"
        print "  REST POST URL: %s" % url
        # NOTE: exc.fp contains the object with the response payload
        error_payload = json.loads(exc.fp.read())
        print "  REST Error Code: %s" % (error_payload['code'])
        print "  REST Error Summary: %s" % (error_payload['summary'])
        print "  REST Error Description: %s" % (error_payload['formattedDescription'])
        print "  HTTP Error Code: %s" % exc.code
        print "  HTTP Error Reason: %s" % exc.reason
    except URLError as exc:
        print "ERROR:"
        print "  REST POST URL: %s" % url
        print "  URL Error Reason: %s" % exc.reason
    return parsed_result

def delete_json(url):
    """Make a REST DELETE call and return the JSON result
       url: the URL to call"""

    parsed_result = []
    try:
        request = urllib2.Request(url)
        request.get_method = lambda: 'DELETE'
        response = urllib2.urlopen(request)
        result = response.read()
        response.close()
        if len(result) != 0:
            parsed_result = json.loads(result)
    except HTTPError as exc:
        print "ERROR:"
        print "  REST DELETE URL: %s" % url
        # NOTE: exc.fp contains the object with the response payload
        error_payload = json.loads(exc.fp.read())
        print "  REST Error Code: %s" % (error_payload['code'])
        print "  REST Error Summary: %s" % (error_payload['summary'])
        print "  REST Error Description: %s" % (error_payload['formattedDescription'])
        print "  HTTP Error Code: %s" % exc.code
        print "  HTTP Error Reason: %s" % exc.reason
    except URLError as exc:
        print "ERROR:"
        print "  REST DELETE URL: %s" % url
        print "  URL Error Reason: %s" % exc.reason
    return parsed_result

if __name__ == '__main__':
    onosCli = OnosCli()

    # Setup the parser
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--command', nargs=argparse.REMAINDER,
                        help="Run arguments to the end of the line as a CLI command")
    parser.add_argument('--onos-ip',
                        help="Set the ONOS IP address (for REST calls)")
    parser.add_argument('--onos-port',
                        help="Set the ONOS port number (for REST calls)")
    parser.add_argument('-t', '--test', nargs='+',
                        help="Test against transcript(s) in FILE (wildcards OK)")

    # Parse the arguments
    parsed_args = parser.parse_args()
    if parsed_args.onos_ip:
        onosCli.onos_ip = parsed_args.onos_ip
    if parsed_args.onos_port:
        onosCli.onos_port = parsed_args.onos_port
    #
    # NOTE: We have to reset the command-line options so the Cmd2 parser
    # doesn't process them again.
    #
    sys.argv = [sys.argv[0]]

    # Run the CLI as appropriate
    if parsed_args.test:
        # Run CLI Transcript Tests
        onosCli.runTranscriptTests(parsed_args.test)
    elif  parsed_args.command:
        # Run arguments as a CLI command
        command_line = ' '.join(parsed_args.command)
        onosCli.onecmd(command_line)
    else:
        # Run interactive CLI
        onosCli.cmdloop()
