# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See LICENSE for more details.
#
# Copyright (c) 2022 ScyllaDB

import uuid
from collections import namedtuple
from pathlib import Path

import pytest

from sdcm.utils.sct_cmd_helpers import get_test_config
from sdcm.sct_config import SCTConfiguration
from sdcm.test_config import TestConfig
from sdcm.utils.azure_utils import AzureService
from unit_tests.unit.provisioner.fake_azure_service import FakeAzureService, FakeVirtualMachines


@pytest.fixture(autouse=True)
def _reset_fake_vm_simulation():
    """Reset fake VM scripts before and after each test."""
    FakeVirtualMachines.clear_scripts()
    yield
    FakeVirtualMachines.clear_scripts()


@pytest.fixture(scope="session")
def test_data_dir() -> Path:
    """Override root test_data_dir: return provisioner's own test_data/ directory."""
    return Path(__file__).parent / "test_data"


@pytest.fixture(scope="session")
def provisioner_dir(test_data_dir: Path) -> Path:
    """Return the path to unit_tests/provisioner/ (for config files co-located with tests)."""
    return test_data_dir.parent


@pytest.fixture(scope="session")
def defaults_dir(provisioner_dir: Path) -> Path:
    """Return the path to the top-level defaults/ directory."""
    return provisioner_dir.parent.parent.parent / "defaults"


@pytest.fixture(scope="session")
def azure_service(tmp_path_factory) -> AzureService:
    run_on_real_azure = False  # make it True to test with real Azure
    if run_on_real_azure:
        # When true this becomes e2e test - takes around 8 minutes (2m provisioning, 6 min cleanup with wait=True)
        return AzureService()
    resources_path = tmp_path_factory.mktemp("azure-provision")
    # print(resources_path)
    return FakeAzureService(resources_path)


@pytest.fixture
def fallback_on_demand(monkeypatch):
    monkeypatch.setenv("SCT_INSTANCE_PROVISION", "spot")
    monkeypatch.setenv("SCT_INSTANCE_PROVISION_FALLBACK_ON_DEMAND", "true")
    monkeypatch.setenv("BUILD_TAG", "FailSpotDB")


@pytest.fixture
def params(monkeypatch, provisioner_dir: Path):
    EnvConfig = namedtuple(
        "EnvConfig",
        [
            "SCT_CLUSTER_BACKEND",
            "SCT_TEST_ID",
            "SCT_CONFIG_FILES",
            "SCT_AZURE_REGION_NAME",
            "SCT_N_DB_NODES",
            "SCT_AZURE_IMAGE_DB",
            "SCT_N_LOADERS",
            "SCT_N_MONITOR_NODES",
            "SCT_AVAILABILITY_ZONE",
            "SCT_IP_SSH_CONNECTIONS",
        ],
    )
    env_config = EnvConfig(
        SCT_CLUSTER_BACKEND="azure",
        SCT_TEST_ID=f"{uuid.uuid4()!s}",
        SCT_CONFIG_FILES=f'["{provisioner_dir.absolute()}/azure_default_config.yaml"]',
        SCT_AZURE_REGION_NAME="['eastus', 'easteu']",
        SCT_N_DB_NODES="3 1",
        SCT_AZURE_IMAGE_DB="/subscriptions/6c268694-47ab-43ab-b306-3c5514bc4112/resourceGroups/"
        "scylla-images/providers/Microsoft.Compute/images/scylla-2024.1.9-x86_64-2024-08-30T04-49-46",
        SCT_N_LOADERS="2 0",
        SCT_N_MONITOR_NODES="1",
        SCT_AVAILABILITY_ZONE="a",
        SCT_IP_SSH_CONNECTIONS="public",
    )
    for key, value in env_config._asdict().items():
        monkeypatch.setenv(key, value)
    return SCTConfiguration()


@pytest.fixture
def test_config(params):
    config = get_test_config()
    config.set_test_id("12345678-87654321")
    TestConfig.SYSLOGNG_ADDRESS = ("localhost", 12345)
    return config
