# Source code of the Ubuntu-it website
# Copyright (C) 2015 Pietro Albini <pietroalbini@ubuntu.com>
# Copyright (C) 2023 shadMod <m.allegro@shadmod.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import os

import click
import uitwww

from pathlib import Path
from fnmatch import fnmatch
from scss.compiler import compile_file
from htmlmin import minify

from .constants import UITWWW_DIR, BASE_DIR
from .utils import ReverseProxied, GunicornInstance
from .src.download.compile_download import CompileVersion


@click.group()
def cli():
    """Ubuntu-it website's command line utility"""
    pass


@cli.command("run")
@click.argument("data")
@click.option(
    "-g", "--gunicorn-config", default=None, help="Path to a gunicorn config file"
)
@click.option("-p", "--port", default=8000, help="Bind that port")
@click.option("--public", help="Make available to the public", is_flag=True)
@click.option("-w", "--workers", help="Number of workers to start", default=3)
@click.option("-d", "--debug", help="Enable debug mode", is_flag=True)
def run(data, gunicorn_config, port, public, workers, debug):
    """Run the application"""
    app = uitwww.create_app(data, debug)
    app.wsgi_app = ReverseProxied(app.wsgi_app)

    host = "127.0.0.1"
    if public:
        host = "0.0.0.0"

    # In debug mode, run the flask builtin webserver
    if debug:
        extra_files = [
            os.path.join(UITWWW_DIR, "data/navbar.yml"),
            os.path.join(UITWWW_DIR, "data/permissions.yml"),
            os.path.join(UITWWW_DIR, "data/redirects.yml"),
            os.path.join(UITWWW_DIR, "data/downloads.toml"),
        ]

        app.run(debug=True, port=port, host=host, extra_files=extra_files)
    # Else run the application with gunicorn
    else:
        options = {
            "bind": host + ":" + str(port),
            "workers": workers,
            "accesslog": "-",
            "errorlog": "-",
        }
        server = GunicornInstance(gunicorn_config, options)
        server.app = app

        try:
            server.run()
        except SystemExit:
            pass


@cli.command("init")
@click.argument("data")
@click.option("-d", "--debug", help="Enable debug mode", is_flag=True)
def init(data, debug):
    """Initialize the data directory"""
    data_path = os.path.expanduser(os.path.abspath(data))
    print("Initializing data directory:", data)
    uitwww.init_data_directory(data_path, debug)
    print("Created data directory:", data)
    compiler = CompileVersion(
        path_out=data_path + "/downloads.toml",
        downloads=UITWWW_DIR + "/src/download/assets/downloads.json",
        info=UITWWW_DIR + "/src/download/assets/info.json",
    )
    compiler.compile_download()
    print("Compile download file")
    uitwww.init_data_downloads(data_path, debug)
    print("Populate data download:", data)


@cli.command("build_scss")
def build_scss():
    """Compile the scss file"""
    print("Start to compile the scss file")
    # init PATTERN and ROOT_SCSS
    PATTERN = "*.scss"
    ROOT_SCSS = os.path.join(BASE_DIR, "assets/scss")
    print("Get all scss")
    # init css_path
    css_path = []
    # get all files with relative path
    for path, subdir, files in os.walk(ROOT_SCSS):
        for name in files:
            # check if filename contain PATTERN
            if fnmatch(name, PATTERN):
                val = os.path.join(path, name).split("scss", 1)[1]
                css_path.append(val.replace(".scss", "")[1:])
    print("Compile the scss file")
    for val in css_path:
        # init path css
        path = os.path.join(UITWWW_DIR, f"static/assets/{val}.min.css")
        # check and mk dir if dir_ not exists
        os.makedirs(os.path.dirname(path), exist_ok=True)
        # open file, compile and write css
        with open(path, "w") as fn:
            fn.write(minify(compile_file(
                Path(BASE_DIR, f"assets/scss/{val}.scss")
            )))
    print("Write and populate css")
