"""TPC-H expected query results provider.

This module provides expected row counts for TPC-H queries based on the official
TPC-H answer sets. It supports scale factor 1.0 from parsed answer files.

VALIDATION MODES
================

TPC-H supports multiple validation modes to handle different testing scenarios:

1. EXACT Mode (Default for SF=1.0 with Reference Seed)
   - Requires exact row count match
   - Used when query parameters match the reference answer files
   - Reference seed for SF=1.0: 0o0101000000 (16843008 decimal)
   - Example: benchbox run --platform duckdb --benchmark tpch --scale 1

2. LOOSE Mode (Auto-Selected with Custom Seeds)
   - Allows ±50% tolerance by default
   - Used when custom seed generates different query parameters
   - Guards against 0-row failures (always fails if expecting >0 but get 0)
   - Example: benchbox run --platform duckdb --benchmark tpch --scale 1 --seed 42

3. RANGE Mode
   - Validates min/max bounds
   - Used for queries with inherent non-determinism
   - Currently not used for TPC-H (reserved for future use)

4. DISABLED Mode
   - Skips all validation
   - Useful for performance testing without correctness checks
   - Example: benchbox run --platform duckdb --benchmark tpch --validation-mode disabled

SEED-BASED PARAMETER GENERATION
================================

TPC-H queries use substitution parameters (:1, :2, etc.) generated by qgen tool.
Different seeds produce different parameter values, which affect query results.

The official TPC-H answer files for SF=1.0 were generated using:
    qgen -r 0101000000  # Octal seed = 16843008 decimal

When using a different seed, the query parameters will differ from the answer files,
causing row count mismatches. BenchBox automatically switches to LOOSE validation
in this case unless explicitly overridden with --validation-mode.

USAGE EXAMPLES
==============

# Auto-detect mode (uses reference seed + EXACT validation at SF=1.0)
benchbox run --platform datafusion --benchmark tpch --scale 1

# Custom seed (auto-switches to LOOSE validation)
benchbox run --platform datafusion --benchmark tpch --scale 1 --seed 99

# Explicit LOOSE mode (±50% tolerance)
benchbox run --platform datafusion --benchmark tpch --scale 1 --validation-mode loose

# Disable validation (performance testing)
benchbox run --platform datafusion --benchmark tpch --scale 1 --validation-mode disabled

# Force EXACT mode with custom seed (will likely fail validation)
benchbox run --platform datafusion --benchmark tpch --scale 1 --seed 99 --validation-mode exact

Copyright 2026 Joe Harris / BenchBox Project

Licensed under the MIT License. See LICENSE file in the project root for details.
"""

import logging

from benchbox.core.expected_results.loader import load_tpch_expected_results
from benchbox.core.expected_results.models import (
    BenchmarkExpectedResults,
    ExpectedQueryResult,
    ValidationMode,
)

logger = logging.getLogger(__name__)


def get_tpch_expected_results(scale_factor: float = 1.0) -> BenchmarkExpectedResults | None:
    """Get expected results for TPC-H queries at a given scale factor.

    This function loads expected row counts from TPC-H answer files (SF=1.0 only currently).
    For scale factors other than 1.0, returns None to trigger graceful validation skip.
    Scale-independent queries can still be validated via registry fallback to SF=1.0.

    Args:
        scale_factor: Scale factor (currently only 1.0 is supported from answer files)

    Returns:
        BenchmarkExpectedResults with all TPC-H query expectations, or None if SF != 1.0
    """
    # Only SF=1.0 is supported - return None for others to trigger graceful SKIP
    if scale_factor != 1.0:
        logger.info(
            f"TPC-H expected results only available for SF=1.0. "
            f"Validation will be skipped for SF={scale_factor}. "
            f"Note: Scale-independent queries (e.g., Q1) may still validate via registry fallback."
        )
        return None

    # Load row counts from answer files (SF=1.0)
    row_counts = load_tpch_expected_results(scale_factor=1.0)

    # Build ExpectedQueryResult objects
    query_results = {}

    # Queries that are scale-independent (same result count regardless of scale factor)
    scale_independent_queries = {
        "1": True,  # Groups by L_RETURNFLAG, L_LINESTATUS (4 combinations)
        # Most other queries are scale-dependent
    }

    for query_id, row_count in row_counts.items():
        is_scale_independent = scale_independent_queries.get(query_id, False)

        query_results[query_id] = ExpectedQueryResult(
            query_id=query_id,
            scale_factor=scale_factor,
            expected_row_count=row_count,
            validation_mode=ValidationMode.EXACT,
            scale_independent=is_scale_independent,
            notes=f"Expected result from TPC-H answer file for SF={scale_factor}",
        )

    return BenchmarkExpectedResults(
        benchmark_name="tpch",
        scale_factor=scale_factor,
        query_results=query_results,
        metadata={
            "source": "TPC-H answer files",
            "answer_files_scale_factor": 1.0,
            "total_queries": len(query_results),
        },
    )


# Register the provider with the global registry
from benchbox.core.expected_results.registry import register_benchmark_provider

register_benchmark_provider("tpch", get_tpch_expected_results)
