# coding: utf-8

# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

"""
TEST FILE: test_sample_copy_analyzer_async.py

DESCRIPTION:
    These tests validate the sample_copy_analyzer.py sample code (async version).
    This sample demonstrates how to copy an analyzer from source to target within the same
    Microsoft Foundry resource using the begin_copy_analyzer API.

USAGE:
    pytest test_sample_copy_analyzer_async.py
"""

import uuid
import pytest
from typing import Dict
from devtools_testutils.aio import recorded_by_proxy_async
from testpreparer_async import ContentUnderstandingPreparer, ContentUnderstandingClientTestBaseAsync
from azure.ai.contentunderstanding.models import (
    ContentAnalyzer,
    ContentAnalyzerConfig,
    ContentFieldSchema,
    ContentFieldDefinition,
    ContentFieldType,
    GenerationMethod,
)


class TestSampleCopyAnalyzerAsync(ContentUnderstandingClientTestBaseAsync):
    """Tests for sample_copy_analyzer.py (async version)"""

    @ContentUnderstandingPreparer()
    @recorded_by_proxy_async
    async def test_sample_copy_analyzer_async(self, contentunderstanding_endpoint: str, **kwargs) -> Dict[str, str]:
        """Test copying an analyzer (within same resource or across resources) (async version).

        This test validates:
        1. Creating a source analyzer with complex configuration
        2. Initiating a copy operation
        3. Verifying the copy completed successfully
        4. Validating the target analyzer has the same configuration

        14_CopyAnalyzer.CopyAnalyzerAsync()

        Note: This test requires copy API support. If not available, test will be skipped.
        """
        # Get variables from test proxy (recorded values in playback, empty dict in recording)
        variables = kwargs.pop("variables", {})

        try:
            client = self.create_async_client(endpoint=contentunderstanding_endpoint)

            # Generate unique analyzer IDs for this test
            # Use variables from recording if available (playback mode), otherwise generate new ones (record mode)
            default_source_id = f"test_analyzer_source_{uuid.uuid4().hex[:16]}"
            default_target_id = f"test_analyzer_target_{uuid.uuid4().hex[:16]}"
            source_analyzer_id = variables.setdefault("copySourceAnalyzerId", default_source_id)
            target_analyzer_id = variables.setdefault("copyTargetAnalyzerId", default_target_id)

            print(f"[INFO] Source analyzer ID: {source_analyzer_id}")
            print(f"[INFO] Target analyzer ID: {target_analyzer_id}")

            assert source_analyzer_id is not None, "Source analyzer ID should not be null"
            assert len(source_analyzer_id) > 0, "Source analyzer ID should not be empty"
            assert target_analyzer_id is not None, "Target analyzer ID should not be null"
            assert len(target_analyzer_id) > 0, "Target analyzer ID should not be empty"
            assert source_analyzer_id != target_analyzer_id, "Source and target IDs should be different"
            print("[PASS] Analyzer IDs verified")

            # Step 1: Create the source analyzer with complex configuration
            source_config = ContentAnalyzerConfig(
                enable_formula=False,
                enable_layout=True,
                enable_ocr=True,
                estimate_field_source_and_confidence=True,
                return_details=True,
            )

            # Verify source config
            assert source_config is not None, "Source config should not be null"
            assert source_config.enable_formula is False, "EnableFormula should be false"
            assert source_config.enable_layout is True, "EnableLayout should be true"
            assert source_config.enable_ocr is True, "EnableOcr should be true"
            assert (
                source_config.estimate_field_source_and_confidence is True
            ), "EstimateFieldSourceAndConfidence should be true"
            assert source_config.return_details is True, "ReturnDetails should be true"
            print("[PASS] Source config verified")

            # Create field schema
            source_field_schema = ContentFieldSchema(
                name="company_schema",
                description="Schema for extracting company information",
                fields={
                    "company_name": ContentFieldDefinition(
                        type=ContentFieldType.STRING, method=GenerationMethod.EXTRACT, description="Name of the company"
                    ),
                    "total_amount": ContentFieldDefinition(
                        type=ContentFieldType.NUMBER,
                        method=GenerationMethod.EXTRACT,
                        description="Total amount on the document",
                    ),
                },
            )

            # Verify field schema
            assert source_field_schema is not None, "Source field schema should not be null"
            assert source_field_schema.name == "company_schema", "Field schema name should match"
            assert (
                source_field_schema.description == "Schema for extracting company information"
            ), "Field schema description should match"
            assert len(source_field_schema.fields) == 2, "Should have 2 fields"
            print(f"[PASS] Source field schema verified: {source_field_schema.name}")

            # Verify individual fields
            assert "company_name" in source_field_schema.fields, "Should contain company_name field"
            company_name_field = source_field_schema.fields["company_name"]
            assert company_name_field.type == ContentFieldType.STRING, "company_name should be String type"
            assert company_name_field.method == GenerationMethod.EXTRACT, "company_name should use Extract method"
            print("[PASS] company_name field verified")

            assert "total_amount" in source_field_schema.fields, "Should contain total_amount field"
            total_amount_field = source_field_schema.fields["total_amount"]
            assert total_amount_field.type == ContentFieldType.NUMBER, "total_amount should be Number type"
            assert total_amount_field.method == GenerationMethod.EXTRACT, "total_amount should use Extract method"
            print("[PASS] total_amount field verified")

            # Create source analyzer
            source_analyzer = ContentAnalyzer(
                base_analyzer_id="prebuilt-document",
                description="Source analyzer for copying",
                config=source_config,
                field_schema=source_field_schema,
                models={"completion": "gpt-4.1"},
                tags={"modelType": "in_development"},
            )

            # Create the source analyzer
            create_poller = await client.begin_create_analyzer(
                analyzer_id=source_analyzer_id, resource=source_analyzer, allow_replace=True
            )
            source_result = await create_poller.result()
            print(f"[PASS] Source analyzer '{source_analyzer_id}' created successfully")

            # Step 2: Copy the analyzer
            # Note: Copy API may require authorization token for cross-resource copying
            # For same-resource copying, no authorization is needed
            print(f"\n[INFO] Attempting to copy analyzer from '{source_analyzer_id}' to '{target_analyzer_id}'")

            # Copy analyzer
            # begin_copy_analyzer requires:
            # - analyzer_id: target analyzer ID
            # - source_analyzer_id: source analyzer ID (as keyword arg)
            copy_poller = await client.begin_copy_analyzer(
                analyzer_id=target_analyzer_id, source_analyzer_id=source_analyzer_id
            )
            copy_result = await copy_poller.result()
            print(f"[PASS] Analyzer copied successfully to '{target_analyzer_id}'")

            print("\n[SUCCESS] All test_sample_copy_analyzer_async assertions passed")
            print("[INFO] Copy analyzer functionality demonstrated")

            # Return variables to be recorded for playback mode
            return variables

        except Exception as e:
            # Let all exceptions fail - don't skip
            raise
        finally:
            # Clean up: delete test analyzers
            try:
                if "source_analyzer_id" in locals() and "client" in locals():
                    await client.delete_analyzer(analyzer_id=source_analyzer_id)  # type: ignore
                    print(f"\n[INFO] Source analyzer deleted: {source_analyzer_id}")  # type: ignore
            except Exception as cleanup_error:
                print(f"\n[WARN] Could not delete source analyzer: {str(cleanup_error)[:100]}")

            try:
                if "target_analyzer_id" in locals() and "client" in locals():
                    # Only try to delete if copy succeeded
                    if "copy_result" in locals():
                        await client.delete_analyzer(analyzer_id=target_analyzer_id)  # type: ignore
                        print(f"[INFO] Target analyzer deleted: {target_analyzer_id}")  # type: ignore
            except Exception as cleanup_error:
                print(f"[WARN] Could not delete target analyzer: {str(cleanup_error)[:100]}")

            try:
                if "client" in locals():
                    await client.close()
            except Exception:
                pass
