import logging as log
import os
import secrets
import traceback
from typing import Any

from flask import Flask, Response, render_template, send_from_directory

from api.views.AvatarsViews import setup_avatar_views
from api.views.InternalViews import setup_internal_views
from api.views.MenuViews import setup_menu_views


class ApiFlaskApp(Flask):
    """
    Subclass Flask app to ease customisation and type checking.

    In order for an instance of this class to be useful,
    the setup method should be called after instantiating.
    """

    def __init__(self, *args: Any, **kwargs: Any):
        super().__init__(*args, **kwargs)
        self.domain = os.environ["DOMAIN"]
        self.url_map.strict_slashes = False
        self._load_config()
        # Minor setup tasks
        self._setup_routes()
        setup_internal_views(self)
        setup_avatar_views(self)
        setup_menu_views(self)

    @property
    def secrets_dir(self) -> str:
        return os.path.join("/tmp", "secrets")

    def setup(self) -> None:
        pass

    def _load_config(self) -> None:
        try:
            # This is not being used anywhere
            self.secret_key = secrets.token_hex()
            # Settings from the environment
            self.config.update(
                {
                    "DOMAIN": self.domain,
                }
            )
        except Exception as e:
            log.error(traceback.format_exc())
            raise

    def _setup_routes(self) -> None:
        """
        Setup routes to Serve static files
        """

        @self.route("/templates/<path:path>")
        def send_templates(path: str) -> Response:
            return send_from_directory(
                os.path.join(self.root_path, "static/templates"), path
            )
