#!/usr/bin/env python3
"""
Export Elasticsearch Index Mapping
===================================
Exports the mapping of an Elasticsearch index to a JSON file.

Usage:
    python export_mapping.py
    python export_mapping.py --index arabic_research
    python export_mapping.py --index arabic_research --output mapping.json
"""

import os
import sys
import json
import argparse
from typing import Dict, Any

try:
    from elasticsearch import Elasticsearch
except ImportError:
    print("ERROR: elasticsearch package not installed.")
    print("Run: pip install elasticsearch")
    sys.exit(1)

try:
    from dotenv import load_dotenv
except ImportError:
    load_dotenv = lambda: None


def load_config() -> Dict[str, str]:
    """Load configuration from .env file."""
    load_dotenv()
    return {
        'es_host': os.getenv('SOURCE_ES_HOST', 'http://localhost:9200'),
        'index': os.getenv('SOURCE_INDEX', 'arabic_research'),
    }


def connect_elasticsearch(host: str) -> Elasticsearch:
    """Create Elasticsearch connection."""
    es = Elasticsearch(
        hosts=[host],
        verify_certs=False,
        request_timeout=60,
    )
    
    if not es.ping():
        raise ConnectionError(f"Cannot connect to Elasticsearch at {host}")
    
    info = es.info()
    print(f"✅ Connected to Elasticsearch {info['version']['number']}")
    return es


def export_mapping(es: Elasticsearch, index: str, output_file: str = None) -> Dict[str, Any]:
    """
    Export index mapping to a file or stdout.
    
    Returns the mapping dict.
    """
    if not es.indices.exists(index=index):
        raise ValueError(f"Index '{index}' does not exist")
    
    # Get mapping
    mapping_response = es.indices.get_mapping(index=index)
    mapping = mapping_response[index]['mappings']
    
    # Get settings (optional, for reference)
    settings_response = es.indices.get_settings(index=index)
    settings = settings_response[index]['settings']
    
    # Build output structure
    output = {
        'index': index,
        'mappings': mapping,
        'settings': {
            'index': {
                'number_of_shards': settings.get('index', {}).get('number_of_shards', '1'),
                'number_of_replicas': settings.get('index', {}).get('number_of_replicas', '1'),
            }
        }
    }
    
    if output_file:
        with open(output_file, 'w', encoding='utf-8') as f:
            json.dump(output, f, indent=2, ensure_ascii=False)
        print(f"✅ Mapping exported to: {output_file}")
    else:
        # Print to stdout
        print(json.dumps(output, indent=2, ensure_ascii=False))
    
    return output


def main():
    parser = argparse.ArgumentParser(description='Export Elasticsearch index mapping')
    parser.add_argument('--index', '-i', help='Index name')
    parser.add_argument('--host', '-H', help='Elasticsearch host URL')
    parser.add_argument('--output', '-o', help='Output file (default: stdout)')
    
    args = parser.parse_args()
    
    config = load_config()
    
    es_host = args.host or config['es_host']
    index = args.index or config['index']
    output_file = args.output
    
    if output_file:
        print(f"📋 Exporting mapping for index: {index}")
    
    try:
        es = connect_elasticsearch(es_host)
        export_mapping(es, index, output_file)
        return 0
        
    except Exception as e:
        print(f"❌ Error: {e}", file=sys.stderr)
        return 1


if __name__ == '__main__':
    sys.exit(main())
