# Copyright © The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""Unit tests for base signing task classes."""

from pathlib import Path
from typing import override
from unittest import mock

from django.db import connections
from django.test import TransactionTestCase

from debusine.artifacts.models import WorkRequestResults
from debusine.signing.tasks import BaseSigningTask
from debusine.tasks.models import BaseDynamicTaskData, BaseTaskData
from debusine.tasks.tests.helpers import (
    ExternalTaskHelperMixin,
    SampleBaseExternalTask,
)


class SampleBaseSigningTask(
    SampleBaseExternalTask[BaseTaskData, BaseDynamicTaskData],
    BaseSigningTask[BaseTaskData, BaseDynamicTaskData],
):
    """Sample class to test BaseSigningTask class."""

    @override
    def run(
        self,
        execute_directory: Path,  # noqa: ARG002, U100
    ) -> WorkRequestResults:
        """Succeed if this task is running in a transaction."""
        return (
            WorkRequestResults.SUCCESS
            if connections["default"].in_atomic_block
            else WorkRequestResults.FAILURE
        )


class SampleBaseSigningTask2Data(BaseTaskData):
    """Data representation for SampleBaseSigningTask2."""

    foo: str


class SampleBaseSigningTask2(
    SampleBaseExternalTask[SampleBaseSigningTask2Data, BaseDynamicTaskData],
    BaseSigningTask[SampleBaseSigningTask2Data, BaseDynamicTaskData],
):
    """Test BaseSigningTask class with jsonschema validation."""

    TASK_VERSION = 1

    @override
    def run(self, execute_directory: Path) -> WorkRequestResults:  # noqa: U100
        """Unused abstract method from BaseExternalTask."""
        raise NotImplementedError()


class BaseSigningTaskTransactionTests(
    ExternalTaskHelperMixin[SampleBaseSigningTask], TransactionTestCase
):
    """Test transactional behaviour of :py:class:`BaseSigningTask`."""

    def test_runs_in_transaction(self) -> None:
        """Tasks are executed in a transaction."""
        task = self.configure_task()
        with mock.patch.object(
            task, "_upload_work_request_debug_logs", autospec=True
        ):
            self.assertEqual(task.execute(), WorkRequestResults.SUCCESS)
