#!/usr/bin/env python3
"""
Valida um arquivo GeoJSON específico contra um schema JSON específico.

Este script recebe dois argumentos da linha de comando:
1. O caminho para o arquivo de schema JSON.
2. O caminho para o arquivo GeoJSON a ser validado.

Requer as bibliotecas `jsonschema` e `rfc3339-validator`.
Instale com: uv pip install jsonschema rfc3339-validator

A biblioteca rfc3339-validator é necessária para validar formatos date-time (RFC3339).
Valida também se todos os valores de 'id' nas features são únicos.
"""

import json
import sys
import os
from jsonschema import validate, ValidationError
from jsonschema import FormatChecker

def validate_single_geojson(schema_path, geojson_path):
    """Valida um único arquivo GeoJSON contra um schema fornecido.

    Args:
        schema_path (str): Caminho para o arquivo de schema JSON.
        geojson_path (str): Caminho para o arquivo GeoJSON.
    """
    print(f"\nValidando '{os.path.basename(geojson_path)}' contra '{os.path.basename(schema_path)}'...")
    print("-" * 70)

    # --- Carregar Schema ---
    try:
        with open(schema_path, 'r', encoding='utf-8') as f:
            schema = json.load(f)
        print(f"[1/3] ✅ Schema '{os.path.basename(schema_path)}' carregado com sucesso.")
    except FileNotFoundError:
        print(f"❌ ERRO: Arquivo de schema não encontrado em: '{schema_path}'")
        return False
    except json.JSONDecodeError as e:
        print(f"❌ ERRO: Falha ao decodificar o JSON do schema '{schema_path}': {e}")
        return False

    # --- Carregar GeoJSON ---
    try:
        with open(geojson_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        print(f"[2/3] ✅ Arquivo GeoJSON '{os.path.basename(geojson_path)}' carregado com sucesso.")
    except FileNotFoundError:
        print(f"❌ ERRO: Arquivo GeoJSON não encontrado em: '{geojson_path}'")
        return False
    except json.JSONDecodeError as e:
        print(f"❌ ERRO: Falha ao decodificar o JSON do arquivo '{geojson_path}': {e}")
        return False

    # --- Realizar Validação do Schema ---
    try:
        # Habilita validação de formatos (date, date-time, email, etc.)
        format_checker = FormatChecker()
        validate(instance=data, schema=schema, format_checker=format_checker)
        print(f"[3/4] ✅ Validação do schema concluída.")
    except ValidationError as e:
        print(f"[3/4] ❌ Validação do schema falhou.")
        print(f"\n🔥 FALHA: O arquivo '{os.path.basename(geojson_path)}' é inválido.")
        print("-" * 20 + " Detalhes do Erro " + "-" * 20)
        print(f"  Mensagem: {e.message}")

        # Formata o caminho do erro para ser mais legível
        if e.absolute_path and len(e.absolute_path) > 0:
            path_str = str(e.absolute_path[0])
            for p in list(e.absolute_path)[1:]:
                path_str += f'[{p}]' if isinstance(p, int) else f'.{p}'
            print(f"  Caminho: {path_str}")
        else:
            print("  Caminho: (raiz do documento)")

        print(f"  Schema Path: {list(e.schema_path)}")
        print("-" * 58)
        return False

    # --- Validar Unicidade dos IDs ---
    print("[4/4] Verificando unicidade dos IDs...")
    features = data.get('features', [])
    if features:
        ids = []
        duplicate_ids = []
        for idx, feature in enumerate(features):
            feature_id = feature.get('properties', {}).get('id')
            if feature_id is not None:
                if feature_id in ids:
                    duplicate_ids.append((feature_id, idx))
                ids.append(feature_id)

        if duplicate_ids:
            print(f"[4/4] ❌ Verificação de unicidade falhou.")
            print(f"\n🔥 FALHA: IDs duplicados encontrados no arquivo '{os.path.basename(geojson_path)}'.")
            print("-" * 20 + " IDs Duplicados " + "-" * 20)
            for dup_id, feature_idx in duplicate_ids:
                print(f"  ID '{dup_id}' está duplicado (feature index: {feature_idx})")
            print("-" * 58)
            return False
        else:
            print(f"[4/4] ✅ Todos os IDs são únicos.")

    print(f"\n🎉 SUCESSO: O arquivo '{os.path.basename(geojson_path)}' é válido.")
    return True

if __name__ == '__main__':
    # Verifica se o número de argumentos está correto
    if len(sys.argv) != 3:
        print("Uso: python validate_geojson.py <caminho_para_schema.json> <caminho_para_geojson.json>")
        print("Exemplo: python scripts/validate_geojson.py schemas/conserva.schema.json schemas/examples/conserva.example.geojson")
        sys.exit(1)
    
    schema_file_path = sys.argv[1]
    geojson_file_path = sys.argv[2]
    
    # Executa a validação e sai com o código de status apropriado
    is_valid = validate_single_geojson(schema_file_path, geojson_file_path)
    
    if not is_valid:
        sys.exit(1)
