# Copyright 2025 - 2025 Aegiq Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from dataclasses import dataclass
from typing import Any

from .job_details import JobDetails
from .status import Status

ARTEMIS_JOB_DETAILS_MAP = {
    "jobId": "job_id",
    "queuePosition": "queue_position",
    "jobStatus": "job_status",
    "createdDate": "created_date",
    "updatedDate": "updated_date",
    "logs": "logs",
    "userExecutionNotes": "notes",
}


@dataclass
class ArtemisJobDetails(JobDetails):
    """Stores all job details returned by Artemis"""

    job_id: int
    queue_position: int | None
    job_status: Status
    created_date: str
    updated_date: str
    logs: list[dict[str, Any]]
    notes: str | None

    def __post_init__(self) -> None:
        """Maps the provided status into one of the available statuses."""
        status_mapping = {
            "Accepted": "Accepted",
            "Scheduled": "Scheduled",
            "Running": "Running",
            "Completed": "Completed",
            "Failed": "Failed",
            "Cancelled": "Cancelled",
            "TimedOut": "Timed Out",
        }
        self.job_status = Status(status_mapping[self.job_status])  # type: ignore[index]


def get_no_results_reason(details: ArtemisJobDetails) -> str:
    """
    Generates a reason why no results were generated by a job, which can be
    appended to an error message.
    """
    if details.job_status in {
        Status.ACCEPTED,
        Status.SCHEDULED,
        Status.RUNNING,
    }:
        return "as the job is not yet complete."
    if details.job_status is Status.FAILED:
        if details.notes:
            return (
                f"as execution of the job failed with reason:\n{details.notes}"
            )
        return "as execution of the job failed."
    if details.job_status is Status.CANCELLED:
        return "as the job was cancelled."
    if details.job_status is Status.TIMEDOUT:
        return "as the job timed-out (likely from a hardware issue)."
    # Note this should never happen but is included just in case.
    return "for an unknown reason."
