# pylint: disable=line-too-long,useless-suppression
# ------------------------------------
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# ------------------------------------
import pytest
import os
from devtools_testutils import recorded_by_proxy, AzureRecordedTestCase, RecordedTransport
from test_base import servicePreparer, fineTuningServicePreparer, modelsServicePreparer
from sample_executor import (
    AdditionalSampleTestDetail,
    SyncSampleExecutor,
    additionalSampleTests,
    get_sample_paths,
    SamplePathPasser,
)
from test_samples_helpers import get_sample_env_vars
from test_fine_tuning_samples_helpers import get_fine_tuning_sample_env_vars


class TestSamples(AzureRecordedTestCase):

    # To run this test with a specific sample, use:
    # pytest tests/samples/test_samples.py::TestSamples::test_agent_tools_samples[sample_agent_memory_search]
    @servicePreparer()
    # @additionalSampleTests(
    #     [
    #         AdditionalSampleTestDetail( # 2/28/2026 westus2 get 500
    #             test_id="sample_agent_azure_function",
    #             sample_filename="sample_agent_azure_function.py",
    #             env_vars={
    #                 "STORAGE_INPUT_QUEUE_NAME": "sanitized_input_queue_name",
    #                 "STORAGE_OUTPUT_QUEUE_NAME": "sanitized_output_queue_name",
    #                 "STORAGE_QUEUE_SERVICE_ENDPOINT": "sanitized_queue_service_endpoint",
    #             },
    #         ),
    #     ]
    # )
    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "agents/tools",
            samples_to_skip=[
                "sample_agent_file_search_structured_inputs.py",  # No issue to run. Just posepone recording.
                "sample_agent_code_interpreter_structured_inputs.py",  # No issue to run. Just posepone recording.
                "sample_agent_azure_function.py",  # In the list of additional sample tests above due to more parameters needed
                "sample_agent_computer_use.py",  # 400 BadRequestError: Invalid URI (URI string too long)
                "sample_agent_browser_automation.py",  # APITimeoutError: request timed out
                "sample_agent_openapi.py",  # 400 2/28/2026 validation/tool_user_error; failing weather GET curl call in OpenAPI tool
                "sample_agent_memory_search.py",  # Skipped until re-enabled and recorded on Foundry endpoint that supports the new versioning schema
            ],
        ),
    )
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_agent_tools_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "memories",
            samples_to_skip=[],
        ),
    )
    @servicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    # To run this test: pytest tests/samples/test_samples.py::TestSamples::test_memory_samples -s
    def test_memory_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "agents",
            samples_to_skip=[
                "sample_external_agents_crud.py",  # Skipped until recordings are available.
                "sample_workflow_multi_agent.py",  # No issue to run.  Just postpone recording.
                "sample_workflow_multi_agent_with_mcp_approval.py",  # No issue to run.  Just postpone recording.
            ],
        ),
    )
    @servicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_agents_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "connections",
            samples_to_skip=[],
        ),
    )
    @servicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_connections_samples(self, sample_path: str, **kwargs) -> None:
        kwargs = kwargs.copy()
        kwargs["connection_name"] = "mcp"
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "files",
            samples_to_skip=[],
        ),
    )
    @servicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_files_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "deployments",
            samples_to_skip=[],
        ),
    )
    @servicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_deployments_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "models",
            samples_to_test=[
                # `sample_models_basic.py` uses the `create()` helper which shells out
                # to AzCopy. AzCopy traffic isn't captured by the test proxy, so the
                # sample can't be replayed from a recording. Live re-recording is still
                # exercised via the standalone tests in `tests/models/`.
                "sample_models_create_and_poll.py",
            ],
        ),
    )
    @modelsServicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_models_samples(self, sample_path: str, **kwargs) -> None:
        import secrets  # local import to avoid module-level dep

        env_vars = get_sample_env_vars(kwargs)
        # Foundry permanently reserves a `<name>/<version>` asset namespace even
        # after `models.delete`, so every live re-recording needs a unique name.
        # Sanitize back to a stable value in conftest so playback URLs match.
        suffix = secrets.token_hex(4) if self.is_live else "00000000"
        env_vars["MODEL_NAME"] = f"recsmplmdl{suffix}"
        env_vars["MODEL_VERSION"] = "1"
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        # `validate_print_calls_by_llm` is intentionally not called: it requires
        # an Azure OpenAI connection on the Foundry project, which the canary
        # project used for `.beta.models` recordings does not have. The sample
        # is still validated end-to-end by `executor.execute()` (any exception
        # fails the test).

    @servicePreparer()
    @additionalSampleTests(
        [
            AdditionalSampleTestDetail(
                test_id="sample_dataset_generation_job_simpleqna_with_prompt_source",
                sample_filename="sample_dataset_generation_job_simpleqna_with_prompt_source.py",
                env_vars={
                    "POLL_INTERVAL_SECONDS": "60",
                },
            ),
        ]
    )
    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "datasets",
            samples_to_skip=[
                "sample_dataset_generation_job_simpleqna_with_prompt_source.py",  # PR #47067: recording not yet available
                "sample_dataset_generation_job_traces_for_finetuning.py",  # PR #47067: recording not yet available
                "sample_dataset_generation_job_simpleqna_for_finetuning.py",  # PR #47067: recording not yet available
                "sample_dataset_generation_job_traces_for_evaluation.py",  # PR #47067: recording not yet available
                "sample_dataset_generation_job_simpleqna_with_agent_source.py",  # PR #47067: recording not yet available
                "sample_dataset_generation_job_simpleqna_with_file_source.py",  # PR #47067: recording not yet available
            ],
        ),
    )
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_datasets_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "chat_completions",
            samples_to_skip=[],
        ),
    )
    @servicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_chat_completions_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @servicePreparer()
    @additionalSampleTests(
        [
            AdditionalSampleTestDetail(
                test_id="sample_create_hosted_agent_from_remote_build",
                sample_filename="sample_create_hosted_agent_from_code.py",
                env_vars={
                    "FOUNDRY_HOSTED_AGENT_REMOTE_BUILD": "true",
                },
            ),
        ]
    )
    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "hosted_agents",
            samples_to_skip=[
                "sample_routines_crud.py",  # Skipped due to service serialization issues
                "sample_routines_with_timer_trigger.py",  # Skipped due to service serialization issues
            ],
        ),
    )
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_hosted_agents_samples(self, sample_path: str, **kwargs) -> None:
        if os.path.basename(sample_path).startswith("sample_create_hosted_agent") and not self.is_live:
            pytest.skip("sample_create_hosted_agent.py is skipped in replay mode due to RBAC complications.")
        env_vars = get_sample_env_vars(kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()

    @pytest.mark.parametrize(
        "sample_path",
        get_sample_paths(
            "finetuning",
            samples_to_skip=[
                "sample_finetuning_reinforcement_job.py",  # 403 PermissionDeniedError: missing Microsoft.MachineLearningServices/workspaces/agents/action
                "sample_finetuning_dpo_job.py",  # 401 AuthenticationError: missing AIServices/agents/write data action
            ],
        ),
    )
    @fineTuningServicePreparer()
    @SamplePathPasser()
    @recorded_by_proxy(RecordedTransport.AZURE_CORE, RecordedTransport.HTTPX)
    def test_finetuning_samples(self, sample_path: str, **kwargs) -> None:
        env_vars = get_fine_tuning_sample_env_vars(sample_path, kwargs)
        executor = SyncSampleExecutor(self, sample_path, env_vars=env_vars, **kwargs)
        executor.execute()
        executor.validate_print_calls_by_llm()
