"""Remaining hunk estimation for session progress."""

from __future__ import annotations

from dataclasses import asdict
import os
import sys

from ..exceptions import CommandError
from ..git_paths import display_path
from ..i18n import _
from ..utils.file_jobs import run_file_jobs, select_file_job_execution
from ..utils.journal import log_journal
from .live_change_jobs import (
    acquire_live_change_count_plan,
    count_eligible_live_text_file,
)


def estimate_remaining_hunks() -> int:
    """Estimate the number of live hunks not yet included, skipped, or discarded."""
    with acquire_live_change_count_plan() as plan:
        execution = select_file_job_execution(
            plan.jobs,
            requested_jobs=os.environ.get("GIT_STAGE_BATCH_JOBS"),
            platform=sys.platform,
            cpu_count=None,
        )
        results = run_file_jobs(
            plan.jobs,
            count_eligible_live_text_file,
            execution=execution,
            repository_root=plan.repository_root,
        )
        stale_result = next(
            (result for result in results if result.stale),
            None,
        )
        if stale_result is not None:
            raise CommandError(
                _(
                    "Working tree file changed while status was being "
                    "calculated: {file}. Retry the status command."
                ).format(file=display_path(stale_result.file_path))
            )

        for result in results:
            log_journal(
                "file_attribution_complete",
                file_path=result.file_path,
                **asdict(result.attribution_metrics),
            )
        return plan.atomic_count + sum(
            result.eligible_count for result in results
        )
