"""Contains all tests for the get_tags_from_common_vars function."""

import os
from unittest.mock import MagicMock, patch

from voraus_pipeline_utils.constants import ENV_VAR_DOCKER_REGISTRY
from voraus_pipeline_utils.methods.docker import get_tags_from_common_vars


@patch("voraus_pipeline_utils.methods.docker.get_all_docker_tags")
@patch("voraus_pipeline_utils.methods.docker.get_docker_tags_from_env")
@patch("voraus_pipeline_utils.methods.docker.get_docker_repositories_from_env")
@patch("voraus_pipeline_utils.methods.docker.get_docker_image_name_from_env")
def test_tags_provided_directly(
    mock_get_docker_image_name_from_env: MagicMock,
    mock_get_docker_repositories_from_env: MagicMock,
    mock_get_docker_tags_from_env: MagicMock,
    mock_get_all_docker_tags: MagicMock,
) -> None:
    # Scenario: Tags are provided directly, so they should be returned as-is.
    tags = ["latest", "1.0"]
    result = get_tags_from_common_vars(tags=tags, repositories=None, image_name=None, registry="example.com")
    assert result == tags
    mock_get_all_docker_tags.assert_not_called()
    mock_get_docker_tags_from_env.assert_not_called()
    mock_get_docker_repositories_from_env.assert_not_called()
    mock_get_docker_image_name_from_env.assert_not_called()


@patch("voraus_pipeline_utils.methods.docker.get_all_docker_tags")
@patch("voraus_pipeline_utils.methods.docker.get_docker_tags_from_env")
@patch("voraus_pipeline_utils.methods.docker.get_docker_repositories_from_env")
@patch("voraus_pipeline_utils.methods.docker.get_docker_image_name_from_env")
def test_tags_not_provided_image_name_provided(
    mock_get_docker_image_name_from_env: MagicMock,
    mock_get_docker_repositories_from_env: MagicMock,
    mock_get_docker_tags_from_env: MagicMock,
    mock_get_all_docker_tags: MagicMock,
) -> None:
    # Scenario: Tags are not provided, but image name is provided. Environment variables are not set.
    image_name = "test-image"
    repositories = ["repo1", "repo2"]
    generated_tags = ["generated-tag1", "generated-tag2"]

    mock_get_all_docker_tags.return_value = generated_tags
    mock_get_docker_tags_from_env.return_value = None

    result = get_tags_from_common_vars(
        tags=None, repositories=repositories, image_name=image_name, registry="example.com"
    )
    assert result == generated_tags
    mock_get_all_docker_tags.assert_called_once_with(
        image_name=image_name, repositories=repositories, registry="example.com"
    )
    mock_get_docker_tags_from_env.assert_called_once()

    mock_get_docker_image_name_from_env.assert_not_called()
    mock_get_docker_repositories_from_env.assert_not_called()


@patch("voraus_pipeline_utils.methods.docker.get_all_docker_tags")
@patch("voraus_pipeline_utils.methods.docker.get_docker_tags_from_env")
@patch("voraus_pipeline_utils.methods.docker.get_docker_repositories_from_env")
@patch("voraus_pipeline_utils.methods.docker.get_docker_image_name_from_env")
def test_tags_fetched_from_environment(
    mock_get_docker_image_name_from_env: MagicMock,
    mock_get_docker_repositories_from_env: MagicMock,
    mock_get_docker_tags_from_env: MagicMock,
    mock_get_all_docker_tags: MagicMock,
) -> None:
    # Scenario: Tags and image name are not provided, should fetch from environment
    image_name = "env-image"
    repositories = ["env-repo1", "env-repo2"]
    env_tags = ["env-tag1", "env-tag2"]

    mock_get_docker_image_name_from_env.return_value = image_name
    mock_get_docker_repositories_from_env.return_value = repositories
    mock_get_docker_tags_from_env.return_value = env_tags

    result = get_tags_from_common_vars(tags=None, repositories=None, image_name=None, registry="example.com")
    assert result == env_tags
    mock_get_docker_image_name_from_env.assert_called_once()
    mock_get_docker_repositories_from_env.assert_called_once()
    mock_get_docker_tags_from_env.assert_called_once()
    mock_get_all_docker_tags.assert_not_called()


@patch.dict(os.environ, {ENV_VAR_DOCKER_REGISTRY: "example.com"})
@patch("voraus_pipeline_utils.methods.docker.get_all_docker_tags")
@patch("voraus_pipeline_utils.methods.docker.get_docker_tags_from_env")
def test_tags_fetched_from_get_all_docker_tags(
    mock_get_docker_tags_from_env: MagicMock,
    mock_get_all_docker_tags: MagicMock,
) -> None:
    # Scenario: Tags are not provided, and get_all_docker_tags is used to generate tags
    image_name = "test-image"
    repositories = ["repo1", "repo2"]
    generated_tags = ["generated-tag1", "generated-tag2"]

    mock_get_docker_tags_from_env.return_value = None
    mock_get_all_docker_tags.return_value = generated_tags

    result = get_tags_from_common_vars(tags=None, repositories=repositories, image_name=image_name)
    assert result == generated_tags
    mock_get_all_docker_tags.assert_called_once_with(
        image_name=image_name, repositories=repositories, registry="example.com"
    )
    mock_get_docker_tags_from_env.assert_called_once()
