# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import re

from scss.compiler import compile_file  # type: ignore
import flask

from aep_site.jinja.env import jinja_env
from aep_site.models.site import Site


ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))
app = flask.Flask("aep", static_folder=f"{ROOT}/aep_site/support/assets/")
app.jinja_env = jinja_env  # type: ignore


@app.route("/")
def hello():
    return flask.render_template("index.html.j2", site=flask.g.site)


@app.route("/<int:aep_id>")
def aep(aep_id: int):
    """Display a single AEP document."""
    return flask.g.site.aeps[aep_id].render()


@app.route("/search")
def search():
    """Display the search page."""
    return flask.render_template(
        "search.html.j2",
        site=flask.g.site,
        path=flask.request.path,
    )


@app.route("/<page>")
@app.route("/<collection>/<page>")
def page(page: str, collection: str = "general"):
    """Display a static page or listing of AEPs in a given scope."""
    site = flask.g.site
    if page in site.scopes:
        return site.scopes[page].render()
    if page in site.aeps_by_slug:
        return site.aeps_by_slug[page].render()
    if collection in site.collections and page in site.collections[collection].pages:
        return site.collections[collection].pages[page].render()
    if collection in site.scopes and int(page) in site.scopes[collection].aeps:
        return site.scopes[collection].aeps[int(page)].render()
    flask.abort(404)


@app.route("/assets/css/<path:css_file>")
def scss(css_file: str):
    """Compile the given SCSS file and return it."""
    scss_file = re.sub(r"\.css$", ".scss", css_file)
    css = compile_file(f"{ROOT}/aep_site/support/scss/{scss_file}")
    return flask.Response(css, mimetype="text/css")


@app.route("/assets/js/search/tipuesearch_content.js")
def search_content():
    """Compile the search content JavaScript and return it."""
    return flask.Response(
        flask.render_template("search.js.j2", site=flask.g.site),
        mimetype="text/javascript",
    )


def site_load_func(src: str):
    """Return a function that loads the site and registers it.

    This is used in cli.py to register to Flask.before_request.
    """

    def fx():
        flask.g.site = Site.load(src)

        # This is the dev server, so plow over whatever the configuration
        # says that the site URL is.
        flask.g.site.config.setdefault("urls", {})
        flask.g.site.config["urls"]["site"] = "http://localhost:4000"

    return fx
