#!/usr/bin/env python
# -*- coding: utf-8 -*-

# AUTOMATICALLY MADE FILE. DO NOT EDIT.
# This file was generated by {{ author }} on {{ current_date }} with Python executable
# {{ sys_executable }}

import logging
import threading
import datetime
from pathlib import Path, PosixPath, WindowsPath

import dash
import dash_core_components as dcc
import dash_html_components as html
from flask_talisman import Talisman
import webviz_config
import webviz_config.plugins
from webviz_config.themes import installed_themes
from webviz_config.common_cache import CACHE
from webviz_config.webviz_store import WEBVIZ_STORAGE
from webviz_config.webviz_assets import WEBVIZ_ASSETS
from webviz_config.utils import deprecate_webviz_settings_attribute_in_dash_app

# We do not want to show INFO regarding werkzeug routing as that is too verbose,
# however we want other log handlers (typically coming from webviz plugin dependencies)
# to be set to user specified log level.
logging.getLogger("werkzeug").setLevel(logging.WARNING)
logging.getLogger().setLevel(logging.{{ loglevel }})

theme = webviz_config.WebvizConfigTheme("{{ theme_name }}")
theme.from_json((Path(__file__).resolve().parent / "theme_settings.json").read_text())

app = dash.Dash(
    __name__,
    external_stylesheets=theme.external_stylesheets,
    assets_folder=Path("resources") / "assets",
    meta_tags=[
        {"name": "viewport", "content": "width=device-width, initial-scale=1"}
    ],
)
app.logger.setLevel(logging.WARNING)

# For signing session cookies
app.server.secret_key = webviz_config.LocalhostToken.generate_token()

server = app.server

app.title = "{{ title }}"
app.config.suppress_callback_exceptions = True

# Create the common webviz_setting object that will get passed as an
# argument to all plugins that request it.
webviz_settings: webviz_config.WebvizSettings = webviz_config.WebvizSettings(
    shared_settings=webviz_config.SHARED_SETTINGS_SUBSCRIPTIONS.transformed_settings(
        {{ shared_settings }}, {{ config_folder }}, {{ portable }} 
    ),
    theme=theme,
)

# Previously, webviz_settings was piggybacked onto the Dash application object.
# For a period of time, keep it but mark access to the webviz_settings attribute
# on the Dash application object as deprecated.
deprecate_webviz_settings_attribute_in_dash_app()
app._deprecated_webviz_settings = {
    "shared_settings" : webviz_settings.shared_settings,
    "theme" : webviz_settings.theme,
    "portable" : {{ portable }},
}

CACHE.init_app(server)

theme.adjust_csp({"script-src": app.csp_hashes()}, append=True)
Talisman(server, content_security_policy=theme.csp, feature_policy=theme.feature_policy, force_https=False, session_cookie_secure=False)

WEBVIZ_STORAGE.use_storage = {{portable}}
WEBVIZ_STORAGE.storage_folder = Path(__file__).resolve().parent / "resources" / "webviz_storage"

WEBVIZ_ASSETS.portable = {{ portable }}

use_oauth2 = False

if {{ not portable }} and not webviz_config.is_reload_process():
    # When Dash/Flask is started on localhost with hot module reload activated,
    # we do not want the main process to call expensive component functions in
    # the layout tree, as the layout tree used on initialization will anyway be called
    # from the child/restart/reload process.
    app.layout = html.Div()
else:
    page_content = {}
    {% for page in pages %}
    page_content["{{page.id}}"] = []
    {% for content in page.content -%}
    {% if content is string %}
    page_content["{{page.id}}"].append(dcc.Markdown(r"""{{ content }}"""))
    {% else %}
    plugin_content = webviz_config.plugins.{{ content._call_signature[0] }}
    if not use_oauth2:
        use_oauth2 = plugin_content.oauth2 if hasattr(plugin_content, "oauth2") else use_oauth2
    page_content["{{page.id}}"].append(plugin_content.{{ content._call_signature[1] }})
    {% endif %}
    {% endfor %}
    {% endfor %}
    app.layout = html.Div(
        className="layoutWrapper", 
        children=[html.Div(
            children=[dcc.Location(
                id='url', refresh=True),
        html.Div(
            className="sideWrapper",
            children=[
            {% for page in pages %}
                dcc.Link(
                    {%- if loop.first -%}
                    "",
                    id="logo",
                    className="styledLogo",
                    href="/",
                    {%- else -%}
                    "{{page.title}}",
                    # We will create a webviz-core-components
                    # component instead of styling dcc.Link's,
                    # then we can more easily change className to
                    # selectedButton for current page.
                    className="styledButton",
                    id="{{page.id}}",
                    href="/{{page.id}}",
                    {%- endif -%}
                    )
                 {{- "" if loop.last else "," -}}
            {% endfor %}
            ])]),
        html.Div(className="pageContent", id="page-content")])

oauth2 = webviz_config.Oauth2(app.server) if use_oauth2 else None

@app.callback(dash.dependencies.Output("page-content", "children"),
              dash.dependencies.Input("url", "pathname"))
def update_page(pathname):
    pathname = pathname.replace("/", "")
    if not pathname:
        pathname = list(page_content.keys())[0] 
    return page_content.get(pathname, "Oooppss... Page not found.")

{{ "WEBVIZ_ASSETS.directly_host_assets(app)" if not portable else ""}}

if __name__ == "__main__":
    # This part is ignored when the webviz app is started
    # using Docker container and uwsgi (e.g. when hosted on Azure).
    #
    # It is used only when directly running this script with Python,
    # which will then initialize a localhost server.

    port = webviz_config.utils.get_available_port(preferred_port=5000)

    token = webviz_config.LocalhostToken(app.server, port, oauth2).one_time_token
    webviz_config.utils.LocalhostOpenBrowser(port, token)

    webviz_config.utils.silence_flask_startup()

    app.run_server(
        host="localhost",
        port=port,
        debug=False,
        use_reloader={{not portable}},
        dev_tools_prune_errors=False,
      {% if not portable -%}
        dev_tools_hot_reload=True,
        dev_tools_hot_reload_interval=1.0,
        dev_tools_silence_routes_logging=False,
      {% endif %}
    )
else:
    # This will be applied if not running on localhost
    if use_oauth2:
        oauth2.set_oauth2_before_request_decorator()
