"""
Load ontology from file tool for the AGS SPARQL Agent.

This tool loads ontology content from TTL files directly into AGS.
"""

import os
import sys
from datetime import datetime
from pathlib import Path

# Add src directory to path for imports
src_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
if src_dir not in sys.path:
    sys.path.insert(0, src_dir)

from ..base_tool import BaseToolMixin, handle_tool_errors, ToolError
from ...utils.agent_utils import get_agent


@handle_tool_errors
async def load_ontology_from_file(
    file_path: str = None,
    target_graph_uri: str = None,
    clear_graph_first: bool = False,
    validate_syntax: bool = True,
    explanation: str = None
) -> str:
    """Load a local TTL (Turtle) file into a named graph in AGS.
    
    This tool loads ontology content from TTL files directly into the
    AGS local volume, with optional syntax validation and graph clearing.
    
    Args:
        file_path: Absolute path to the TTL file (required)
        target_graph_uri: URI of the named graph to load into (required)
        clear_graph_first: If true, clear the target graph before loading
        validate_syntax: If true, validate TTL syntax before loading
        explanation: Human-readable description of the loading operation (required)
        
    Returns:
        JSON response with loading results and statistics
    """
    BaseToolMixin.validate_required_param(file_path, "file_path")
    BaseToolMixin.validate_required_param(target_graph_uri, "target_graph_uri")
    BaseToolMixin.validate_required_param(explanation, "explanation")
    BaseToolMixin.validate_uri(target_graph_uri, "target_graph_uri")
    BaseToolMixin.validate_file_path(file_path, must_exist=True)
    
    agent = await get_agent()
    file_path_obj = Path(file_path)
    
    # Read the TTL file
    with open(file_path_obj, 'r', encoding='utf-8') as f:
        ttl_content = f.read()
    
    if not ttl_content.strip():
        raise ToolError("File is empty or contains only whitespace")
    
    # Validate TTL syntax if requested
    triple_count = 0
    if validate_syntax:
        try:
            from rdflib import Graph
            temp_graph = Graph()
            temp_graph.parse(data=ttl_content, format='turtle')
            triple_count = len(temp_graph)
        except Exception as parse_error:
            raise ToolError(f"TTL syntax validation failed: {str(parse_error)}")
    else:
        # Estimate triple count by counting '.' that end statements
        triple_count = ttl_content.count(' .')
    
    start_time = datetime.now()
    
    # Clear target graph if requested
    if clear_graph_first:
        clear_query = f"DELETE WHERE {{ GRAPH <{target_graph_uri}> {{ ?s ?p ?o . }} }}"
        agent.anzo_client.update_journal(clear_query)
    
    # Convert TTL content to SPARQL INSERT DATA format
    try:
        from rdflib import Graph
        rdflib_available = True
    except ImportError:
        rdflib_available = False
    
    if rdflib_available:
        # Parse TTL content into RDFLib graph
        temp_graph = Graph()
        temp_graph.parse(data=ttl_content, format='turtle')
        triple_count = len(temp_graph)
        
        # Convert to SPARQL INSERT DATA format
        triples_nt = []
        for subject, predicate, object in temp_graph:
            triple_nt = f"    {subject.n3()} {predicate.n3()} {object.n3()} ."
            triples_nt.append(triple_nt)
        
        sparql_insert = f"""INSERT DATA {{
    GRAPH <{target_graph_uri}> {{
{chr(10).join(triples_nt)}
    }}
}}"""
        method_used = "INSERT DATA with parsed triples (RDFLib)"
    else:
        # Fallback: Simple text-based conversion
        lines = ttl_content.split('\n')
        filtered_lines = []
        
        for line in lines:
            stripped = line.strip()
            if (not stripped.startswith('@prefix') and 
                not stripped.startswith('#') and 
                stripped and
                not stripped.startswith('@base')):
                # Convert common prefixed names to full URIs
                line = line.replace('owl:', '<http://www.w3.org/2002/07/owl#>')
                line = line.replace('rdfs:', '<http://www.w3.org/2000/01/rdf-schema#>')
                line = line.replace('xsd:', '<http://www.w3.org/2001/XMLSchema#>')
                line = line.replace('rdf:', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#>')
                filtered_lines.append('    ' + line)
        
        triple_count = len([l for l in filtered_lines if l.strip().endswith(' .')])
        
        sparql_insert = f"""INSERT DATA {{
    GRAPH <{target_graph_uri}> {{
{chr(10).join(filtered_lines)}
    }}
}}"""
        method_used = "INSERT DATA with text conversion (fallback)"
    
    # Execute the INSERT operation
    agent.anzo_client.update_journal(sparql_insert)
    execution_time = (datetime.now() - start_time).total_seconds()
    
    return BaseToolMixin.create_success_response({
        "file_path": file_path,
        "target_graph_uri": target_graph_uri,
        "triples_loaded": triple_count,
        "execution_time_seconds": execution_time,
        "graph_cleared": clear_graph_first,
        "validation_passed": validate_syntax,
        "explanation": explanation,
        "method": method_used,
        "rdflib_used": rdflib_available
    }, f"Successfully loaded {triple_count} triples from TTL file into named graph")