"""Contains all integration tests for the protect CLI."""

import os
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest
from typer.testing import CliRunner

from voraus_pipeline_utils.cli.main import app

# Define test parameters for all supported file types
# To add new file types: add a new tuple with (cli_arg, api_type, extension)
FILE_TYPE_PARAMS = [
    ("wheel", "python", ".whl"),  # wheel files map to "python" API endpoint
    ("elf", "elf", ""),  # elf files typically have no extension
]


@pytest.mark.parametrize(("file_type", "api_file_type", "extension"), FILE_TYPE_PARAMS)
@patch.dict(
    os.environ,
    {
        "PROTECTOR_ACCESS_KEY_ID": "test_key_id",
        "PROTECTOR_ACCESS_SECRET_KEY": "test_secret_key",
    },
)
@patch("voraus_pipeline_utils.cli.protect.protect_file")
def test_protect_success(
    protect_file_mock: MagicMock,
    cli_runner: CliRunner,
    file_type: str,
    api_file_type: str,
    extension: str,
) -> None:
    result = cli_runner.invoke(
        app=app, args=["protect", file_type, f"/path/to/file{extension}", "--identifier=test-package-1"]
    )
    assert result.exit_code == 0

    protect_file_mock.assert_called_once_with(
        file_path=Path(f"/path/to/file{extension}"),
        file_type=api_file_type,
        identifier="test-package-1",
        api_endpoint="https://protector.vorausrobotik.com",
        access_key_id="test_key_id",
        access_secret_key="test_secret_key",  # noqa: S106
        replace=True,
    )


@pytest.mark.parametrize(("file_type", "api_file_type", "extension"), FILE_TYPE_PARAMS)
@patch.dict(
    os.environ,
    {
        "PROTECTOR_ACCESS_KEY_ID": "test_key_id",
        "PROTECTOR_ACCESS_SECRET_KEY": "test_secret_key",
    },
)
@patch("voraus_pipeline_utils.cli.protect.protect_file")
def test_protect_with_custom_endpoint(
    protect_file_mock: MagicMock,
    cli_runner: CliRunner,
    file_type: str,
    api_file_type: str,
    extension: str,
) -> None:
    result = cli_runner.invoke(
        app=app,
        args=[
            "protect",
            file_type,
            f"/path/to/file{extension}",
            "--identifier=test-package-1",
            "--api-endpoint=https://custom.endpoint.com",
        ],
    )
    assert result.exit_code == 0

    protect_file_mock.assert_called_once_with(
        file_path=Path(f"/path/to/file{extension}"),
        file_type=api_file_type,
        identifier="test-package-1",
        api_endpoint="https://custom.endpoint.com",
        access_key_id="test_key_id",
        access_secret_key="test_secret_key",  # noqa: S106
        replace=True,
    )


@pytest.mark.parametrize(("file_type", "api_file_type", "extension"), FILE_TYPE_PARAMS)
@patch.dict(
    os.environ,
    {
        "PROTECTOR_ACCESS_KEY_ID": "test_key_id",
        "PROTECTOR_ACCESS_SECRET_KEY": "test_secret_key",
    },
)
@patch("voraus_pipeline_utils.cli.protect.protect_file")
def test_protect_no_replace(
    protect_file_mock: MagicMock,
    cli_runner: CliRunner,
    file_type: str,
    api_file_type: str,
    extension: str,
) -> None:
    result = cli_runner.invoke(
        app=app,
        args=["protect", file_type, f"/path/to/file{extension}", "--identifier=test-package-1", "--no-replace"],
    )
    assert result.exit_code == 0

    protect_file_mock.assert_called_once_with(
        file_path=Path(f"/path/to/file{extension}"),
        file_type=api_file_type,
        identifier="test-package-1",
        api_endpoint="https://protector.vorausrobotik.com",
        access_key_id="test_key_id",
        access_secret_key="test_secret_key",  # noqa: S106
        replace=False,
    )


@pytest.mark.parametrize(("file_type", "api_file_type", "extension"), FILE_TYPE_PARAMS)
@patch("voraus_pipeline_utils.cli.protect.protect_file")
def test_protect_with_explicit_credentials(
    protect_file_mock: MagicMock,
    cli_runner: CliRunner,
    file_type: str,
    api_file_type: str,
    extension: str,
) -> None:
    result = cli_runner.invoke(
        app=app,
        args=[
            "protect",
            file_type,
            f"/path/to/file{extension}",
            "--identifier=test-package-1",
            "--access-key-id=explicit_key",
            "--access-secret-key=explicit_secret",
        ],
    )
    assert result.exit_code == 0

    protect_file_mock.assert_called_once_with(
        file_path=Path(f"/path/to/file{extension}"),
        file_type=api_file_type,
        identifier="test-package-1",
        api_endpoint="https://protector.vorausrobotik.com",
        access_key_id="explicit_key",
        access_secret_key="explicit_secret",  # noqa: S106
        replace=True,
    )


@pytest.mark.parametrize(("file_type", "api_file_type", "extension"), FILE_TYPE_PARAMS)
@patch.dict(
    os.environ,
    {
        "PROTECTOR_API_ENDPOINT": "https://env-endpoint.example.com",
        "PROTECTOR_ACCESS_KEY_ID": "test_key_id",
        "PROTECTOR_ACCESS_SECRET_KEY": "test_secret_key",
    },
)
@patch("voraus_pipeline_utils.cli.protect.protect_file")
def test_protect_with_endpoint_from_env(
    protect_file_mock: MagicMock,
    cli_runner: CliRunner,
    file_type: str,
    api_file_type: str,
    extension: str,
) -> None:
    result = cli_runner.invoke(
        app=app, args=["protect", file_type, f"/path/to/file{extension}", "--identifier=test-package-1"]
    )
    assert result.exit_code == 0

    protect_file_mock.assert_called_once_with(
        file_path=Path(f"/path/to/file{extension}"),
        file_type=api_file_type,
        identifier="test-package-1",
        api_endpoint="https://env-endpoint.example.com",
        access_key_id="test_key_id",
        access_secret_key="test_secret_key",  # noqa: S106
        replace=True,
    )
