from __future__ import unicode_literals
from __future__ import print_function

from ...command import SubCommand
from ...wsgi import WSGIApplication
from ...compat import text_type
from ...context.expression import Expression


class PreCache(SubCommand):
    """Load resources in to cache in advance"""

    help = "pre-cache resources to speed up initial requests "

    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 projects settings file",
        )

    def run(self):
        console = self.console

        console.text("loading project", bold=True)
        application = WSGIApplication(
            self.location,
            self.get_settings(),
            disable_autoreload=True,
            master_settings=self.master_settings,
        )
        archive = application.archive

        try:
            templates_fs = archive.get_filesystem("templates")
        except KeyError:
            self.error("templates filesystem not found")
        else:
            template_engine = archive.get_template_engine()
            paths = list(templates_fs.walk.files(filter=["*.html"]))

            console.text("pre-caching templates", bold=True)

            failed_templates = []
            with console.progress("pre-caching templates", width=20) as progress:
                progress.set_num_steps(len(paths))
                for path in paths:
                    progress.step(msg=path)
                    try:
                        template_engine.env.get_template(path)
                    except Exception as e:
                        failed_templates.append((path, text_type(e)))

        if archive.has_cache("parser"):
            parser_cache = archive.get_cache("parser")

            console.text("pre-caching expressions", bold=True)

            elements = []
            for lib in archive.libs.values():
                for _type, _elements in lib.elements_by_type.items():
                    elements.extend(_elements)

            with console.progress("caching expressions", width=20) as progress:
                progress.set_num_steps(len(elements))
                for el in elements:
                    progress.step(msg=getattr(el, "libid", ""))
                    el.compile_expressions()

            Expression.dump(parser_cache)
        else:
            console.error("no 'parser' cache available to store expressions")

        console.text("done", fg="green", bold=True)
