#!/usr/bin/env python3
"""Expose organized independent and joint results inside experiments/."""
from __future__ import annotations

import html
import os
import re
import shutil
from pathlib import Path
from urllib.parse import urlsplit, urlunsplit

PROJECT = Path(__file__).resolve().parents[1]
MAP = {
    "AC28": (PROJECT / "results/independent/AC28", PROJECT / "experiments/AC28/results"),
    "ME1a_DT": (PROJECT / "results/independent/ME1a_DT", PROJECT / "experiments/ME1a_DT/results"),
    "together": (PROJECT / "results/together", PROJECT / "experiments/together/results"),
}
ATTRIBUTE = re.compile(r'''(?P<name>\b(?:href|src))=(?P<quote>["'])(?P<url>[^"']+)(?P=quote)''')


def rewrite(page: Path, source_root: Path, destination_root: Path) -> None:
    source_page = source_root / page.relative_to(destination_root)

    def replace(match: re.Match[str]) -> str:
        value = match.group("url")
        parsed = urlsplit(value)
        if parsed.scheme or parsed.netloc or value.startswith(("/", "#")):
            return match.group(0)
        target = (source_page.parent / parsed.path).resolve()
        if target.is_relative_to(source_root.resolve()):
            return match.group(0)
        relative = os.path.relpath(target, page.parent).replace(os.sep, "/")
        url = urlunsplit(("", "", relative, parsed.query, parsed.fragment))
        return f'{match.group("name")}={match.group("quote")}{html.escape(url, quote=True)}{match.group("quote")}'

    page.write_text(ATTRIBUTE.sub(replace, page.read_text(encoding="utf-8")), encoding="utf-8")


def link(page: Path, target: Path, label: str) -> str:
    relative = os.path.relpath(target, page.parent).replace(os.sep, "/")
    return f'<a href="{html.escape(relative, quote=True)}">{html.escape(label)}</a>'


def landing(path: Path, title: str, entries: list[tuple[Path, str]]) -> None:
    links = "".join(f"<li>{link(path, target, label)}</li>" for target, label in entries)
    path.write_text(f'''<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>{html.escape(title)}</title><style>body{{font:17px/1.5 system-ui,sans-serif;max-width:900px;margin:auto;padding:30px;background:#f4f7fb;color:#172333}}li{{margin:16px 0}}a{{color:#145e93}}</style>
<h1>{html.escape(title)}</h1><ul>{links}</ul></html>''', encoding="utf-8")


def main() -> None:
    for name, (source, destination) in MAP.items():
        destination.parent.mkdir(parents=True, exist_ok=True)
        shutil.copytree(source, destination, dirs_exist_ok=True,
                        ignore=shutil.ignore_patterns(".DS_Store", "__pycache__"))
        count = 0
        for source_page in source.rglob("*.html"):
            rewrite(destination / source_page.relative_to(source), source, destination)
            count += 1
        root = destination.parent
        entries = [(destination / "index.html", "All results"),
                   (destination / "models/index.html", "Individual models" if name != "together" else "Models trained together"),
                   (destination / "preprocessing/index.html", "Preprocessing and graphs") if name != "together" else
                   (destination / "graph_node_study/index.html", "Graph node study")]
        if name != "together":
            entries.append((PROJECT / "experiments/together/results/models/index.html", "AC28 + ME1a models trained together"))
        landing(root / "index.html", f"{name}: experiment results", entries)
        print(f"{name}: {count} organized pages copied to {destination}")
    landing(PROJECT / "experiments/index.html", "Experiments: all results", [
        (PROJECT / "experiments/AC28/index.html", "AC28 individual results"),
        (PROJECT / "experiments/ME1a_DT/index.html", "ME1a individual results"),
        (PROJECT / "experiments/together/index.html", "AC28 + ME1a models trained together"),
        (PROJECT / "experiments/preprocess_size_desicisions/index.html", "Preprocessing size comparisons and decisions"),
    ])


if __name__ == "__main__":
    main()
