#!/usr/bin/python3 -s
import shlex
import subprocess
from itertools import chain
from l3tlib import CommandError
from l3tlib.command import L3tCommand
from l3tlib.template import format_objects, make_color_helper

L3S_CONFIG_SECTION = "l3se"


class Search(L3tCommand):

    usage = ("%prog [--customer CUSTOMER] [--agent AGENT] "
             " [--expr EXPRESSION] [NAMEDSEARCH]")
    descr = """Search for incidents

Filtering options such as --customer or --agent can be used, or a named
search based on a Solid Ground search expression can be referred.

Named searches can be defined in the [%s] section of the configuration. See
Run with -l to see the list of those currently available.
""" % (L3S_CONFIG_SECTION)

    def init_parser(self, parser):
        super(Search, self).init_parser(parser)
        parser.add_option("-R", "--not-running", dest="running",
                          default=True, action="store_false",
                          help="Don't list only running incidents")
        parser.add_option("-u", "--user", "-a", "--agent",
                          dest="agent", default=None,
                          help="filter by agent")
        parser.add_option("-c", "--customer", default=None,
                          help="filter by customer")
        parser.add_option("--sr", "--supportrequest",
                          dest="supportrequest", default=None,
                          help="filter by SR ID")
        parser.add_option("-l", "--list-searches", default=False,
                          action="store_true",
                          help="list named searches")
        parser.add_option("--expr", default=None,
                          help=("filter by a raw Solid Ground query "
                                "expression (see the URLs rendered from the "
                                "search page to have an idea)"))
        parser.add_option("--run", default=None,
                          help=("run another command with the incident "
                                "number as the next argument"))

    def parse_args(self, parser, args):
        opts, values = super(Search, self).parse_args(parser, args)
        if not any((opts.agent, opts.customer, opts.expr, values,
                    opts.supportrequest, opts.list_searches)):
            parser.error("missing a filter option")
        if values and opts.expr:
            parser.error("cannot use --expr and named searches")
        return opts, values

    def _get_searches(self):
        config = self.config.config_object()
        for option in config.options(L3S_CONFIG_SECTION):
            expr = config.get(L3S_CONFIG_SECTION, option)
            yield option, expr

    def _get_search(self, name):
        config = self.config.config_object()
        if name not in config.options(L3S_CONFIG_SECTION):
            raise CommandError("no such named search %r" % (name))
        return config.get(L3S_CONFIG_SECTION, name)

    def _search_incidents(self):
        if self.args:
            expressions = [self._get_search(arg) for arg in self.args]
        else:
            expr = self.opts.expr or ""
            expressions = [expr]
        results = (self.l3t.search_incidents(agent=self.opts.agent,
                                             customer=self.opts.customer,
                                             running=self.opts.running,
                                             sr=self.opts.supportrequest,
                                             base_expr=expr)
                   for expr in expressions)
        incidents = chain.from_iterable(results)
        return format_objects(self.config.l3t.incident_oneline, incidents,
                              C=make_color_helper(self.config))

    def run(self):
        if self.opts.list_searches:
            for name, expr in self._get_searches():
                print("%s: %s" % (name, expr))
        else:
            if self.opts.run:
                cmdline = shlex.split(self.opts.run)
            for incident, formatted in self._search_incidents():
                if not self.opts.quiet:
                    print(formatted)
                if self.opts.run:
                    subprocess.call(cmdline + [str(incident.id)], shell=False)


Search().main()
