#
# Erminig - Classe globale pour la récupération des dernières versions de softs.
# Copyright (C) 2025 L0m1g
# Sous licence DOUARN - Voir le fichier LICENCE pour les détails
#
# Ce fichier fait partie du projet Erminig.
# Libre comme l’air, stable comme un menhir, et salé comme le beurre.
#

import json
from pathlib import Path
import yaml


from erminig.controllers.evezh.parsers.github import GitHubSource
from erminig.controllers.evezh.parsers.http import HttpSource
from erminig.controllers.evezh.parsers.sourceforge import SourceForgeRSS
from erminig.handlers.versions import handle_new_version
from erminig.models.db import ErminigDB
from erminig.models import upstreams, versions


def load_state(path):
    if Path(path).exists():
        return json.loads(Path(path).read_text())
    return {}


def save_state(path, state):
    Path(path).write_text(json.dumps(state, indent=2))


def sync_db(config_path):
    config = get_config(config_path)
    print(config)

    with ErminigDB() as db:
        for proj in config:
            name = proj["name"]
            type_ = "http"
            if "github" in proj:
                type_ = "github"
                url = proj["github"]
            elif "sourceforge" in proj:
                type_ = "sourceforge"
                url = proj["sourceforge"]
            else:
                url = proj.get("url", "")

            pattern = proj.get("pattern", "")
            file = proj.get("file", None)
            upstreams.upsert_upstream(db, name, type_, url, pattern, file)

    print("Synchronisation terminée.")


def make_source(name, config):
    if "github" in config:
        return GitHubSource(name, config)
    elif "sourceforge" in config:
        return SourceForgeRSS(name, config)
    else:
        return HttpSource(name, config)


def apply_template(name, template_name, templates):
    tpl = templates.get(template_name)
    if not tpl:
        raise ValueError(f"Template '{template_name}' non trouvé.")
    return {
        "url": tpl["url"].replace("@NAME@", name),
        "pattern": tpl["pattern"].replace("@NAME@", name),
    }


def get_config(path):
    with open(path) as f:
        full = yaml.safe_load(f)

    templates = full.get("templates", {})
    projects = full.get("projects", [])

    resolved = []

    for proj in projects:
        name = proj["name"]
        new_proj = proj.copy()

        if "template" in proj:
            tpl = apply_template(name, proj["template"], templates)
            new_proj["url"] = tpl["url"]
            new_proj["pattern"] = tpl["pattern"]

        resolved.append(new_proj)

    return resolved


def check_versions(config_path, state=None):
    results = []
    with ErminigDB() as db:
        for row in upstreams.get_all_upstreams(db):
            proj = dict(row)
            if proj["type"] == "github":
                proj["github"] = proj["url"]
            elif proj["type"] == "sourceforge":
                proj["sourceforge"] = proj["url"]
            else:
                proj["url"] = proj["url"]
            upstream_id = proj["id"]
            name = proj["name"]
            source = make_source(name, proj)
            latest = source.get_latest()
            if latest:
                results.append(latest)
                version = latest["version"]
                url = latest["url"]
                handle_new_version(db, upstream_id, name, version, url)
            elif state and name in state:
                print(f"[{name}] Serveur HS. On garde l’ancienne version.")
                results.append(
                    {
                        "name": name,
                        "version": state[name]["version"],
                        "url": state[name]["url"],
                    }
                )
            else:
                print(f"[{name}] Aucune version détectée.")

    return results
