#!/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 decimal import Decimal
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, parse_float=Decimal)
        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, parse_float=Decimal)
        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)