#!/usr/bin/env python3
import argparse
import os
import pathlib
import requests
import subprocess
import xml.etree.ElementTree as ET
import yaml
from concurrent.futures import ThreadPoolExecutor
from functools import partial


BASE_REPO_URL = "https://repo.eclipse.org/content/repositories/releases"
JGIT_GROUP_ID = "org.eclipse.jgit"
JGIT_PARENT_ARTIFACT_ID = "org.eclipse.jgit-parent"
DOWNLOAD_DIR = "staging-deploy"


class Dumper(yaml.Dumper):
    def increase_indent(self, flow=False, *args, **kwargs):
        return super().increase_indent(flow=flow, indentless=False)


def fetch_and_parse_pom(url):
    """Fetches and parses a Maven POM file from a URL."""
    print(f"Fetching parent POM from {url}")
    try:
        response = requests.get(url)
        response.raise_for_status()
        return ET.fromstring(response.content)
    except requests.exceptions.RequestException as e:
        print(f"Error fetching POM: {e}")
        exit(1)


def get_pom_info(pom_root):
    """Extracts GAV and modules from a parsed POM XML."""
    ns = {"m": "http://maven.apache.org/POM/4.0.0"}

    group_id_elem = pom_root.find("m:groupId", ns)
    if group_id_elem is None:
        group_id_elem = pom_root.find("m:parent/m:groupId", ns)

    version_elem = pom_root.find("m:version", ns)
    if version_elem is None:
        version_elem = pom_root.find("m:parent/m:version", ns)

    java_version_elem = None
    for prop in pom_root.findall("m:properties", ns):
        java_version_elem = prop.find("m:java.version", ns)
        if java_version_elem is not None:
            break

    info = {
        "groupId": group_id_elem.text,
        "artifactId": pom_root.find("m:artifactId", ns).text,
        "version": version_elem.text,
        "java_version": java_version_elem.text,
        "modules": [
            module.text for module in pom_root.findall("m:modules/m:module", ns)
        ],
    }
    return info


def download_artifacts(artifacts_to_download):
    """Downloads all artifacts for the given GAVs into the DOWNLOAD_DIR."""
    for artifact in artifacts_to_download:
        group_path = artifact["groupId"].replace(".", "/")
        base_url = f"{BASE_REPO_URL}/{group_path}/{artifact['artifactId']}/{artifact['version']}"
        group_download_dir = f"{DOWNLOAD_DIR}/{group_path}"
        artifact_download_dir = (
            f"{group_download_dir}/{artifact['artifactId']}/{artifact['version']}"
        )
        if not os.path.exists(artifact_download_dir):
            os.makedirs(artifact_download_dir)

        filenames = [f"{artifact['artifactId']}-{artifact['version']}.pom"]
        if "parent" not in artifact["artifactId"]:
            filenames.extend(
                [
                    f"{artifact['artifactId']}-{artifact['version']}.jar",
                    f"{artifact['artifactId']}-{artifact['version']}-sources.jar",
                    f"{artifact['artifactId']}-{artifact['version']}-javadoc.jar",
                    f"{artifact['artifactId']}-{artifact['version']}-cyclonedx.json",
                    f"{artifact['artifactId']}-{artifact['version']}.sh",
                ]
            )

        print(
            f"\nDownloading artifacts for {artifact['groupId']}:{artifact['artifactId']}:{artifact['version']}"
        )
        download_task = partial(download_file, artifact_download_dir, base_url)
        with ThreadPoolExecutor(max_workers=8) as executor:
            executor.map(download_task, filenames)


def download_file(artifact_download_dir, base_url, filename):
    """Downloads the given file from base_url to artifact_download_dir in a Maven repository layout"""
    url = f"{base_url}/{filename}"
    local_path = os.path.join(artifact_download_dir, filename)

    try:
        with requests.get(url, stream=True) as r:
            if r.status_code == 200:
                with open(local_path, "wb") as f:
                    for chunk in r.iter_content(chunk_size=8192):
                        f.write(chunk)
                print(f"  Downloaded: {filename}")
            elif r.status_code == 404:
                pass
            else:
                print(
                    f"  Warning: Failed to download {filename} (Status: {r.status_code})"
                )
    except requests.exceptions.RequestException as e:
        print(f"  Error downloading {filename}: {e}")


def sign_artifacts(passphrase_file):
    """GPG signs all artifacts under DOWNLOAD_DIR"""
    artifact_dir = pathlib.Path(DOWNLOAD_DIR)
    print("Signing artifacts")
    for file in artifact_dir.rglob("*"):
        if file.is_file() and file.suffix in {".jar", ".pom", ".sh", ".json"}:
            try:
                subprocess.run(
                    [
                        "gpg",
                        "--batch",
                        "--yes",
                        "--pinentry-mode",
                        "loopback",
                        "--passphrase-file",
                        passphrase_file,
                        "--armor",
                        "--detach-sign",
                        str(file),
                    ],
                    check=True,
                )
                print(f"  Signed: {str(file)}")
            except subprocess.CalledProcessError as e:
                print(f"Error signing {file}: {e.stderr}")


def jreleaser_set_values(jgit_version, java_version):
    """Generates jreleaser.yml from template and sets values extracted from parent pom"""
    if not jgit_version:
        print("jgit_version undefined")
    if not java_version:
        print("java_version undefined")

    with open("jreleaser.yml.template", "r") as f:
        data = yaml.safe_load(f)

    data["project"]["version"] = jgit_version
    data["project"]["languages"]["java"]["version"] = java_version

    with open("jreleaser.yml", "w") as f:
        yaml.dump(data, f, sort_keys=False, Dumper=Dumper)


def main():
    """Main execution function."""
    parser = argparse.ArgumentParser(
        description="""Download artifacts of a JGit release from repo.eclipse.org.""",
        usage="%(prog)s <version> [--passphrase_file <path to passphrase file> (default: ~/.gnupg/passphrase)]",
    )
    # 'version' as a positional argument
    parser.add_argument(
        "version", help="The JGit version to process (e.g., 5.13.4.202507202350-r)."
    )
    parser.add_argument(
        "--passphrase_file",
        help="Path to file containing gpg passphrase",
        default=f"{pathlib.Path.home()}/.gnupg/passphrase",
    )
    args = parser.parse_args()
    jgit_version = args.version
    passphrase_file = args.passphrase_file

    group_path = JGIT_GROUP_ID.replace(".", "/")
    filename = f"{JGIT_PARENT_ARTIFACT_ID}-{jgit_version}.pom"
    parent_pom_url = f"{BASE_REPO_URL}/{group_path}/{JGIT_PARENT_ARTIFACT_ID}/{jgit_version}/{filename}"

    pom_root = fetch_and_parse_pom(parent_pom_url)
    parent_info = get_pom_info(pom_root)

    if parent_info["version"] != jgit_version:
        print(
            f"Warning: The version in the POM ('{parent_info['version']}') does not match the requested version ('{jgit_version}')."
        )
        print("Proceeding with the version found in the POM file.")

    print("\n--- Project Information ---")
    print(f"GroupId:    {parent_info['groupId']}")
    print(f"ArtifactId: {parent_info['artifactId']}")
    print(f"Version:    {parent_info['version']}")
    print(f"Found {len(parent_info['modules'])} modules.")

    artifacts_to_process = []
    artifacts_to_process.append(
        {
            "groupId": parent_info["groupId"],
            "artifactId": parent_info["artifactId"],
            "version": parent_info["version"],
        }
    )
    for module in parent_info["modules"]:
        if not module.endswith((".test", ".coverage", ".benchmarks")):
            artifacts_to_process.append(
                {
                    "groupId": parent_info["groupId"],
                    "artifactId": module,
                    "version": parent_info["version"],
                }
            )

    download_artifacts(artifacts_to_process)
    sign_artifacts(passphrase_file)
    jreleaser_set_values(parent_info["version"], parent_info["java_version"])


if __name__ == "__main__":
    main()
