#!/usr/bin/python3
# -*- coding: utf-8 -*-

# This is a simple helper script for downloading and unminimizing all the
# linked external references to CSS and JS files which are used in the files
# within the folder './strawberry/static/'.
#
# To prevent a later side loading of these files we ship them within the binary
# package. The replacement of the URIs for loading the data in these HTML
# files is done by debian/rules at build time.


# import pprint
import os
import sys
import shutil

from typing import Any
from urllib.request import urlretrieve
from bs4 import BeautifulSoup


# The upstream files we do grep the external resources.
data_files = [
    "apollo-sandbox.html",
    "graphiql.html",
    "pathfinder.html",
]

ANSI_GREEN = "\u001b[32m"
ANSI_RESET = "\u001b[0m"
ANSI_RED = "\u001b[31m"
ANSI_YELLOW = "\u001b[33m"
ANSI_BOLD = "\u001b[1m"
ANSI_WHITE = "\u001b[37m"
ANSI_BLUE = "\u001b[34m"


def html_file_read(file: str) -> str:
    """
    Open an reads the give file.
    """
    with open(f"strawberry/static/{file}", "r", encoding="utf-8") as data:
        return data.read()


def clear_folder(foldername: str) -> None:
    """
    Remove the whole given folder if existing and recreate it.
    """
    if not os.path.exists(foldername):
        # Create folder if not existing.
        os.makedirs(foldername)
    else:
        # Remove existing folder and recreate it immediately.
        shutil.rmtree(foldername, ignore_errors=False)
        os.makedirs(foldername)


def get_file_count(html_object: str, f_type: str) -> int:
    """
    Count all the 'script' or 'css' elements within the given file/object.
    """
    return len(html_object.select(f_type))


def check_js_beautify() -> None:
    """
    Simple check if we can find '/usr/bin/js-beautify' on the system.
    Just check for a symlink here! js-beautify is provided by
    'node-js-beautify' (which we prefer) but also by 'jsbeautifier'.
    """
    if not os.path.islink("/usr/bin/js-beautify"):
        print(f"\n{ANSI_RED}Failed to find helper \'js-beautify\'!{ANSI_RESET}")  # noqa: E501
        print(f"Please install the package \'{ANSI_YELLOW}node-js-beautify{ANSI_RESET}\'\n")  # noqa: E501
        sys.exit(1)


if __name__ == "__main__":

    check_js_beautify()

    clear_folder("./debian/missing-sources")
    clear_folder("./debian/static")

    data_structure: dict[Any] = {}
    print()

    for html_file in data_files:
        clear_folder(f"./debian/static/{html_file}")
        clear_folder(f"./debian/missing-sources/{html_file}")

        urls = []

        print(
            f"Getting CSS/JS content data from {ANSI_GREEN}./strawberry/static/{html_file}{ANSI_RESET}"  # noqa: E501
        )
        html_data = BeautifulSoup(html_file_read(html_file), "html.parser")

        entries_js = get_file_count(html_data, "script")
        entries_css = get_file_count(html_data, "link")

        LOOP: int = 0
        while LOOP <= entries_js - 1:
            data = str(html_data.select("script")[LOOP]).split()
            if any("src=" in sub for sub in data) is True:
                urls.append(html_data.select("script")[LOOP].get("src"))
            LOOP = LOOP + 1

        LOOP = 0
        while LOOP <= entries_css - 1:
            data = str(html_data.select("link")[LOOP]).split()
            if any("href=" and "stylesheet" in sub for sub in data) is True:
                urls.append(html_data.select("link")[LOOP].get("href"))
            LOOP = LOOP + 1

        data_structure.update(
            {
                html_file: {
                    "entries_css": entries_css,
                    "entries_js": entries_js,
                    "urls": urls,
                }
            }
        )

#    pprint.pp(data_structure) # Only needed while debugging.
    print()

    # Downloading and create an non minimized variant from the collected
    # linked files into './debian/missing-sources'.
    for entry in sorted(data_structure.keys()):
        print(f"{ANSI_BOLD}Download data for:{ANSI_RESET} {ANSI_YELLOW}{entry}{ANSI_RESET}")  # noqa: E501
        for url in sorted(data_structure.get(entry).get("urls")):
            minimized_file_name: str = str(url.rsplit("/", 1)[1])
            target_folder_minimized: str = f"./debian/static/{entry}"
            target_folder_unminimized: str = f"./debian/missing-sources/{entry}"  # noqa: E501

            print(
                f""" ˪ {ANSI_GREEN}{minimized_file_name}{ANSI_RESET}
     Downloading '{ANSI_YELLOW}{url}{ANSI_RESET}' to '{ANSI_BOLD}{ANSI_BLUE}{target_folder_minimized}/{ANSI_RESET}'."""  # noqa: E501
            )

            urlretrieve(url, f"{target_folder_minimized}/{minimized_file_name}")  # noqa: E501

            if ".min" in minimized_file_name:
                unminimized_file_name: str = minimized_file_name.replace(".min", "")  # noqa: E501
            else:
                unminimized_file_name: str = minimized_file_name
            print(
                f"     Unminimizing '{ANSI_YELLOW}{target_folder_minimized}/{minimized_file_name}{ANSI_RESET}' to '{ANSI_BLUE}{target_folder_unminimized}/{unminimized_file_name}{ANSI_RESET}'."  # noqa: E501
            )
            os.system(
                f"js-beautify {target_folder_minimized}/{minimized_file_name} > {target_folder_unminimized}/{unminimized_file_name}"  # noqa: E501
            )
        print()
