# Copyright (c) 2026 Airbyte, Inc., all rights reserved.
"""`airbyte-cloud jobs` commands.

## CLI reference

The commands below are regenerated by `poe docs-generate` via cyclopts's
programmatic docs API; see `docs/generate_cli.py`.

.. include:: ../../../docs/generated/airbyte-cloud-cli/jobs.md
   :start-line: 2
"""

from __future__ import annotations

from typing import Annotated

from airbyte import cloud
from airbyte.exceptions import PyAirbyteInputError
from cyclopts import Parameter

from airbyte_cloud_cli._base import App, app
from airbyte_cloud_cli._input import (
    ClientIdArg,
    ClientSecretArg,
    JobIdArg,
    PositionalIdArg,
    PublicApiRootArg,
    WorkspaceIdArg,
    resolve_entity_id,
)
from airbyte_cloud_cli._output import json_output

jobs_app = App(name="jobs", help="View Airbyte sync jobs.")
app.command(jobs_app)


def _resolve_job_id(args: tuple[str, ...], job_id: int | None) -> int:
    resolved_job_id = resolve_entity_id(
        args,
        str(job_id) if job_id is not None else None,
        option_name="--job-id",
    )
    if not resolved_job_id.isdecimal():
        raise PyAirbyteInputError(
            message="Job ID must be a positive integer.",
            context={"option": "--job-id"},
        )
    return int(resolved_job_id)


def _workspace(
    *,
    workspace_id: str | None,
    client_id: str | None,
    client_secret: str | None,
    public_api_root: str | None,
) -> cloud.CloudWorkspace:
    return cloud.CloudWorkspace(
        workspace_id=workspace_id,
        client_id=client_id,
        client_secret=client_secret,
        api_root=public_api_root,
    )


def _get_job_info(workspace: cloud.CloudWorkspace, job_id: int):
    return workspace.get_job_info(job_id)


@jobs_app.command(name="list")
def list_(
    *,
    connection_id: Annotated[
        str, Parameter(help="The connection ID to list jobs for.")
    ],
    limit: Annotated[int, Parameter(help="Maximum number of jobs to return.")] = 20,
    workspace_id: WorkspaceIdArg = None,
    client_id: ClientIdArg = None,
    client_secret: ClientSecretArg = None,
    public_api_root: PublicApiRootArg = None,
) -> None:
    """List recent jobs for a connection."""
    workspace = _workspace(
        workspace_id=workspace_id,
        client_id=client_id,
        client_secret=client_secret,
        public_api_root=public_api_root,
    )
    results = workspace.get_connection(connection_id).get_previous_sync_logs(
        limit=limit
    )
    json_output([job.get_info() for job in results])


@jobs_app.command
def describe(
    *job_id_args: PositionalIdArg,
    job_id: JobIdArg = None,
    workspace_id: WorkspaceIdArg = None,
    client_id: ClientIdArg = None,
    client_secret: ClientSecretArg = None,
    public_api_root: PublicApiRootArg = None,
) -> None:
    """Describe a specific job."""
    resolved_job_id = _resolve_job_id(job_id_args, job_id)
    workspace = _workspace(
        workspace_id=workspace_id,
        client_id=client_id,
        client_secret=client_secret,
        public_api_root=public_api_root,
    )
    json_output(_get_job_info(workspace, resolved_job_id))


@jobs_app.command
def wait(
    *job_id_args: PositionalIdArg,
    job_id: JobIdArg = None,
    wait_timeout: Annotated[
        int,
        Parameter(help="Maximum seconds to wait for job completion."),
    ] = 300,
    workspace_id: WorkspaceIdArg = None,
    client_id: ClientIdArg = None,
    client_secret: ClientSecretArg = None,
    public_api_root: PublicApiRootArg = None,
) -> None:
    """Wait for a job to complete."""
    resolved_job_id = _resolve_job_id(job_id_args, job_id)
    workspace = _workspace(
        workspace_id=workspace_id,
        client_id=client_id,
        client_secret=client_secret,
        public_api_root=public_api_root,
    )
    job = _get_job_info(workspace, resolved_job_id)
    result = workspace.get_connection(job.connection_id).get_sync_result(
        resolved_job_id
    )
    if result is None:
        raise PyAirbyteInputError(message="Sync result is not available.")
    result.wait_for_completion(wait_timeout=wait_timeout)
    json_output(result.get_info())
