# Copyright (C) 2026 GoodData Corporation

"""Shared scope resolution for MCP and CLI validation flows."""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

from aida_mcp.utils.git import (
    get_remote_default_branch_ref,
    get_tracking_upstream_ref,
    list_changed_files,
    list_changed_files_vs_upstream,
    list_remotes,
    list_tracked_files_under,
)


@dataclass(frozen=True, slots=True)
class ValidationScopeSelection:
    changed_paths: list[str]
    scope_source: str
    resolved_upstream_ref: str | None
    upstream_source: str | None
    upstream_ref: str | None
    head_ref: str


def resolve_validation_scope(
    *,
    workspace_root: Path,
    scope: str,
    focus_paths: list[str] | None = None,
    upstream_ref: str | None = None,
    head_ref: str = "HEAD",
) -> ValidationScopeSelection:
    if focus_paths:
        return ValidationScopeSelection(
            changed_paths=list_tracked_files_under(workspace_root, focus_paths),
            scope_source="focus_paths",
            resolved_upstream_ref=None,
            upstream_source=None,
            upstream_ref=upstream_ref,
            head_ref=head_ref,
        )

    if scope == "pre_commit":
        return ValidationScopeSelection(
            changed_paths=list_changed_files(workspace_root, include_untracked=True),
            scope_source="git.pre_commit",
            resolved_upstream_ref=None,
            upstream_source=None,
            upstream_ref=upstream_ref,
            head_ref=head_ref,
        )

    resolved_upstream = upstream_ref or get_tracking_upstream_ref(workspace_root)
    upstream_source = "upstream_ref" if upstream_ref else "git.@{u}"
    if resolved_upstream is None:
        remotes = list_remotes(workspace_root)
        if len(remotes) == 1:
            resolved_upstream = get_remote_default_branch_ref(workspace_root, remotes[0])
            upstream_source = f"git.remote_head({remotes[0]})"

    if resolved_upstream is None:
        raise ValueError(
            "pre_push requires an upstream. Set tracking upstream for this branch or pass upstream_ref. "
            "Examples: upstream_ref='@{u}' or upstream_ref='origin/main'."
        )

    changed_vs_upstream = list_changed_files_vs_upstream(
        workspace_root,
        upstream_ref=resolved_upstream,
        head_ref=head_ref,
    )
    dirty = list_changed_files(workspace_root, include_untracked=True)
    return ValidationScopeSelection(
        changed_paths=sorted({*changed_vs_upstream, *dirty}),
        scope_source="git.pre_push",
        resolved_upstream_ref=resolved_upstream,
        upstream_source=upstream_source,
        upstream_ref=upstream_ref,
        head_ref=head_ref,
    )
