"""Maintainer trust scorer — detects suspicious account age and ownership changes."""
from __future__ import annotations

from datetime import datetime, timezone

from pyguard.models import Finding, PackageMetadata, PyPIRelease, Severity

_DATE_FMT = "%Y-%m-%dT%H:%M:%S"


def _parse_dt(ts: str) -> datetime | None:
    for fmt in ("%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%d %H:%M:%S"):
        try:
            return datetime.strptime(ts[:19], fmt).replace(tzinfo=timezone.utc)
        except ValueError:
            continue
    return None


def analyze_maintainer(
    package_name: str,
    version: str,
    metadata: PackageMetadata,
) -> list[Finding]:
    findings: list[Finding] = []
    history = metadata.release_history
    if not history:
        return findings

    findings.extend(_check_new_package(package_name, version, history))
    findings.extend(_check_first_release_age(package_name, version, history))
    findings.extend(_check_ownership_change(package_name, version, history))
    findings.extend(_check_no_project_links(package_name, version, metadata))
    return findings


def _check_new_package(
    package_name: str, version: str, history: list[PyPIRelease]
) -> list[Finding]:
    """Flag packages whose first-ever upload is very recent."""
    findings: list[Finding] = []
    first = history[0]
    first_dt = _parse_dt(first.upload_time)
    if first_dt is None:
        return findings
    age_days = (datetime.now(tz=timezone.utc) - first_dt).days
    if age_days < 7:
        findings.append(
            Finding(
                severity=Severity.HIGH,
                title="Package is brand-new (< 7 days old)",
                description=(
                    f"'{package_name}' was first uploaded {age_days} day(s) ago. "
                    "New packages have no community audit history."
                ),
                layer="static",
                package=package_name,
                version=version,
                evidence={"first_upload": first.upload_time, "age_days": age_days},
                confidence=0.8,
                category="maintainer_trust",
                remediation="Verify the publisher identity before installing.",
            )
        )
    elif age_days < 30:
        findings.append(
            Finding(
                severity=Severity.MEDIUM,
                title="Package is very new (< 30 days old)",
                description=(
                    f"'{package_name}' was first uploaded {age_days} day(s) ago. "
                    "It has limited community audit history."
                ),
                layer="static",
                package=package_name,
                version=version,
                evidence={"first_upload": first.upload_time, "age_days": age_days},
                confidence=0.65,
                category="maintainer_trust",
                remediation="Check the project's GitHub repository and review recent commits.",
            )
        )
    return findings


def _check_first_release_age(
    package_name: str, version: str, history: list[PyPIRelease]
) -> list[Finding]:
    """Flag if the current version is the very first release (no track record)."""
    findings: list[Finding] = []
    if len(history) == 1:
        findings.append(
            Finding(
                severity=Severity.LOW,
                title="First-ever release of this package",
                description=(
                    f"Version '{version}' is the only release ever published for '{package_name}'. "
                    "No track record exists."
                ),
                layer="static",
                package=package_name,
                version=version,
                evidence={"total_releases": 1},
                confidence=0.6,
                category="maintainer_trust",
                remediation="Verify the package is intentional and inspect source code.",
            )
        )
    return findings


def _check_ownership_change(
    package_name: str, version: str, history: list[PyPIRelease]
) -> list[Finding]:
    """
    Detect suspiciously rapid version bumps that might indicate takeover.
    If the time between the two most recent releases is under 2 hours, flag it.
    """
    findings: list[Finding] = []
    if len(history) < 2:
        return findings
    prev_release = history[-2]
    curr_release = history[-1]
    prev_dt = _parse_dt(prev_release.upload_time)
    curr_dt = _parse_dt(curr_release.upload_time)
    if prev_dt is None or curr_dt is None:
        return findings
    gap_minutes = (curr_dt - prev_dt).total_seconds() / 60
    if 0 < gap_minutes < 120:
        findings.append(
            Finding(
                severity=Severity.HIGH,
                title="Suspiciously rapid version release",
                description=(
                    f"Version '{curr_release.version}' was released only "
                    f"{int(gap_minutes)} minute(s) after '{prev_release.version}'. "
                    "This pattern is associated with supply-chain takeover attacks."
                ),
                layer="static",
                package=package_name,
                version=version,
                evidence={
                    "previous_version": prev_release.version,
                    "previous_upload": prev_release.upload_time,
                    "current_upload": curr_release.upload_time,
                    "gap_minutes": round(gap_minutes, 1),
                },
                confidence=0.75,
                category="maintainer_trust",
                remediation="Audit the diff between the two versions before installing.",
            )
        )
    return findings


def _check_no_project_links(
    package_name: str, version: str, metadata: PackageMetadata
) -> list[Finding]:
    """Flag packages that have neither a homepage nor any project URLs."""
    findings: list[Finding] = []
    if not metadata.home_page and not metadata.project_urls:
        findings.append(
            Finding(
                severity=Severity.LOW,
                title="No project homepage or links",
                description=(
                    f"'{package_name}' has no homepage or project URLs in its PyPI metadata. "
                    "Legitimate packages typically link to their source repository."
                ),
                layer="static",
                package=package_name,
                version=version,
                evidence={},
                confidence=0.55,
                category="maintainer_trust",
                remediation="Research the package before use.",
            )
        )
    return findings
