from ...command import SubCommand
from ...wsgi import WSGIApplication
from ...console import ConsoleHighlighter
from ...tools import url_join
from ...http import StatusCode

class URLHighlight(ConsoleHighlighter):
    styles = {
        None: "bold blue",
        "asterix": "bold yellow",
        "param": "bold magenta"
    }

    highlights = [
        r'(?P<param>\{.*?\})',
        r'(?P<asterix>\*)',
    ]


class TargetHighlight(ConsoleHighlighter):
    styles = {
        "lib": "bold blue",
        "name": "bold green",
        "hash": "white"
    }

    highlights = [
        r'(?P<lib>.*?)(?P<hash>#)(?P<name>.*?)[,\s$]',
    ]


class URLS(SubCommand):
    """List URLs"""
    help = "list URLs"

    def add_arguments(self, parser):
        parser.add_argument("-l", "--location", dest="location", default=None, metavar="PATH",
                            help="location of the Moya server code")
        parser.add_argument("-i", "--ini", dest="settings", default=None, metavar="SETTINGSPATH",
                            help="path to project settings file")
        parser.add_argument("--server", dest="server", default="main", metavar="SERVERREF",
                            help="server element to use")
        parser.add_argument("--sort", "-s", dest="sort", default=False, action="store_true",
                            help="sort URL output")
        parser.add_argument('-m', '--method', dest="method", default=None, metavar="VERB",
                            help="only show urls for the given method")
        parser.add_argument('-a', '--app', dest="app", metavar="APPLICATION", default=None,
                            help="only show urls for given app")
        parser.add_argument('--handler', default=None, metavar="STATUS",
                            help="show handlers for the given error")

    def run(self):
        args = self.args

        application = WSGIApplication(self.location,
                                      self.get_settings(),
                                      args.server,
                                      disable_autoreload=True)
        urlmapper = application.server.urlmapper
        urls = []

        def render_urlmapper(app_name, parent_url, urlmapper):
            for route in urlmapper.routes:
                if route.partial:
                    render_urlmapper(app_name, url_join(parent_url, route.route), route.target)
                else:
                    if args.handler:
                        handler = StatusCode(args.handler)
                        if handler not in route.handlers:
                            continue
                    else:
                        if args.method and not route.match_method(args.method, None):
                            continue
                        if route.handlers:
                            continue
                        if args.app and args.app != app_name:
                            continue
                    urls.append((
                                ", ".join(route.methods or ['*']),
                                url_join(parent_url, route.route),
                                app_name,
                                route.name or '',
                                ", ".join(route.target)))

        for route in urlmapper.routes:
            app_name = route.name or ''
            render_urlmapper(app_name, route.route, route.target)

        if args.sort:
            urls.sort(key=lambda row: row[1])

        def highlight_url(text):
            return URLHighlight.highlight(text)

        def highlight_target(text):
            return TargetHighlight.highlight(text)

        self.console.table(urls,
                           ["method(s)", "URL", "app", "name", "target(s)"],
                           cell_processors={1: highlight_url, 4: highlight_target})
