import json
from typing import Callable

from wanna.core.deployment.io import IOMixin
from wanna.core.deployment.models import (
    ContainerArtifact,
    JsonArtifact,
    PathArtifact,
    PushResult,
    PushTask,
)
from wanna.core.loggers.wanna_logger import get_logger

logger = get_logger(__name__)


class ArtifactsPushMixin(IOMixin):
    def push_artifacts(
        self, docker_pusher: Callable[[list[str]], None], push_tasks: list[PushTask]
    ) -> PushResult:
        def push_containers(container_artifacts: list[ContainerArtifact]):
            for artifact in container_artifacts:
                with logger.user_spinner(f"Pushing {artifact.name.lower()} to {artifact.tags}"):
                    docker_pusher(artifact.tags)

        def push_manifests(manifest_artifacts: list[PathArtifact]):
            for artifact in manifest_artifacts:
                with logger.user_spinner(
                    f"Pushing {artifact.name.lower()} to {artifact.destination}"
                ):
                    self.upload_file(artifact.source, artifact.destination)

        def push_json(artifacts: list[JsonArtifact]):
            for artifact in artifacts:
                with logger.user_spinner(
                    f"Pushing {artifact.name.lower()} to {artifact.destination}"
                ):
                    self.write(artifact.destination, json.dumps(artifact.json_body))

        results: PushResult = []

        for push_task in push_tasks:
            push_containers(container_artifacts=push_task.container_artifacts)
            push_manifests(manifest_artifacts=push_task.manifest_artifacts)
            push_json(artifacts=push_task.json_artifacts)
            results.append(
                (
                    push_task.container_artifacts,
                    push_task.manifest_artifacts,
                    push_task.json_artifacts,
                )
            )

        return results
