# 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_create_analyzer.py

DESCRIPTION:
    These tests validate the sample_create_analyzer.py sample code.
    This sample demonstrates how to create a custom analyzer with a field schema to extract
    structured data from documents.

USAGE:
    pytest test_sample_create_analyzer.py
"""

import pytest
import uuid
from typing import Dict
from azure.core.exceptions import ResourceNotFoundError
from devtools_testutils import recorded_by_proxy
from testpreparer import ContentUnderstandingPreparer, ContentUnderstandingClientTestBase
from azure.ai.contentunderstanding.models import (
    ContentAnalyzer,
    ContentAnalyzerConfig,
    ContentFieldDefinition,
    ContentFieldSchema,
)


class TestSampleCreateAnalyzer(ContentUnderstandingClientTestBase):
    """Tests for sample_create_analyzer.py"""

    @ContentUnderstandingPreparer()
    @recorded_by_proxy
    def test_sample_create_analyzer(self, contentunderstanding_endpoint: str, **kwargs) -> Dict[str, str]:
        """Test creating a custom analyzer with field schema.

        This test validates:
        1. Analyzer ID generation
        2. Field schema definition with multiple field types
        3. Analyzer configuration
        4. Model mappings
        5. Analyzer creation operation

        04_CreateAnalyzer.CreateAnalyzerAsync()
        """
        # Get variables from test proxy (recorded values in playback, empty dict in recording)
        variables = kwargs.pop("variables", {})

        client = self.create_client(endpoint=contentunderstanding_endpoint)

        # Generate a unique analyzer ID
        # Use variables from recording if available (playback mode), otherwise generate new one (record mode)
        default_analyzer_id = f"test_custom_analyzer_{uuid.uuid4().hex[:16]}"
        analyzer_id = variables.setdefault("createAnalyzerId", default_analyzer_id)
        assert analyzer_id and analyzer_id.strip(), "Analyzer ID should not be empty"
        print(f"[PASS] Analyzer ID generated: {analyzer_id}")

        # Define field schema with custom fields
        # This example demonstrates three extraction methods:
        # - extract: Literal text extraction
        # - generate: AI-generated values based on content interpretation
        # - classify: Classification against predefined categories
        field_schema = ContentFieldSchema(
            name="company_schema",
            description="Schema for extracting company information",
            fields={
                "company_name": ContentFieldDefinition(
                    type="string",
                    method="extract",
                    description="Name of the company",
                    estimate_source_and_confidence=True,
                ),
                "total_amount": ContentFieldDefinition(
                    type="number",
                    method="extract",
                    description="Total amount on the document",
                    estimate_source_and_confidence=True,
                ),
                "document_summary": ContentFieldDefinition(
                    type="string", method="generate", description="A brief summary of the document content"
                ),
                "document_type": ContentFieldDefinition(
                    type="string",
                    method="classify",
                    description="Type of document",
                    enum=["invoice", "receipt", "contract", "report", "other"],
                ),
            },
        )

        # Validate field schema
        assert field_schema and field_schema.fields, "Field schema should have fields"
        assert len(field_schema.fields) == 4, "Field schema should have 4 fields"
        assert field_schema.name == "company_schema", "Field schema name should match"
        print(f"[PASS] Field schema defined with {len(field_schema.fields)} fields")

        # Validate each field definition
        for field_name, field_def in field_schema.fields.items():
            assert (
                field_def.type and field_def.method and field_def.description
            ), f"Field {field_name} should have type, method, and description"
            assert field_def.method in ["extract", "generate", "classify"], f"Field {field_name} method should be valid"

        # Verify enum for classify field
        document_type_field = field_schema.fields["document_type"]
        assert (
            document_type_field.enum and len(document_type_field.enum) == 5
        ), "Document type should have 5 enum values"
        print("[PASS] Field definitions validated")

        # Create analyzer configuration
        config = ContentAnalyzerConfig(
            enable_formula=True,
            enable_layout=True,
            enable_ocr=True,
            estimate_field_source_and_confidence=True,
            return_details=True,
        )

        assert config.enable_formula and config.enable_layout and config.enable_ocr, "Core features should be enabled"
        print("[PASS] Analyzer configuration created")

        # Create custom analyzer definition
        custom_analyzer = ContentAnalyzer(
            base_analyzer_id="prebuilt-document",
            description="Custom analyzer for extracting company information",
            config=config,
            field_schema=field_schema,
            models={"completion": "gpt-4.1", "embedding": "text-embedding-3-large"},
        )

        assert custom_analyzer.base_analyzer_id == "prebuilt-document", "Base analyzer should be prebuilt-document"
        assert custom_analyzer.models and len(custom_analyzer.models) >= 2, "Should have at least 2 model mappings"
        print("[PASS] Custom analyzer definition validated")

        # Create the analyzer
        try:
            poller = client.begin_create_analyzer(analyzer_id=analyzer_id, resource=custom_analyzer)
            result = poller.result()

            # Verify operation completed
            assert poller.done(), "Operation should be completed"
            print(f"[PASS] Analyzer '{analyzer_id}' created successfully")

            # Verify result properties if available
            if result:
                result_id = getattr(result, "analyzer_id", None) or getattr(result, "id", None)
                if result_id:
                    assert result_id == analyzer_id, "Result analyzer ID should match"
                    print(f"[PASS] Result analyzer ID verified: {result_id}")

        except ResourceNotFoundError as proxy_error:
            # Check if this is a test proxy playback error (missing recording)
            error_msg = str(proxy_error)
            if "Unable to find a record for the request" in error_msg:
                # This is a test proxy error - recording is missing or outdated, let it fail
                raise
            # Otherwise, it's a real API error - let it fail, don't skip
            raise
        except Exception as e:
            error_msg = str(e)
            print(f"\n[ERROR] Analyzer creation failed: {error_msg}")
            # Let all exceptions fail - don't skip
            raise
        finally:
            # Cleanup: Delete the analyzer
            try:
                client.delete_analyzer(analyzer_id=analyzer_id)
                print(f"[PASS] Cleanup: Analyzer '{analyzer_id}' deleted")
            except Exception as e:
                print(f"[WARN] Cleanup failed: {str(e)}")

        print("\n[SUCCESS] All test_sample_create_analyzer assertions passed")

        # Return variables to be recorded for playback mode
        return variables
