"""
Update AGS configuration tool for the AGS SPARQL Agent.

This tool executes SPARQL UPDATE operations against the AGS transactional RDF triplestore.
"""

import os
import sys
import asyncio
from datetime import datetime

# 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 update_ags_configuration(
    sparql: str = None,
    explanation: str = None,
    dry_run: bool = False
) -> str:
    """Execute SPARQL UPDATE operations against AGS transactional RDF triplestore.
    
    This tool uses the update_journal method for SPARQL UPDATE operations like 
    INSERT, DELETE, INSERT DATA, DELETE DATA to modify AGS configurations,
    ontologies, data layers, dashboard settings, and other AGS instance data.
    
    Args:
        sparql: SPARQL UPDATE query string (INSERT/DELETE/WITH operations)
        explanation: Human-readable description of the operation
        dry_run: If true, validate query without executing
        
    Returns:
        JSON response with AGS configuration update results or validation info
    """
    BaseToolMixin.validate_required_param(sparql, "sparql")
    
    # Validate SPARQL UPDATE syntax
    sparql_upper = sparql.upper().strip()
    valid_update_starts = ["INSERT", "DELETE", "WITH", "DROP", "CLEAR", "LOAD", "CREATE"]
    
    if not any(sparql_upper.startswith(start) for start in valid_update_starts):
        raise ToolError(f"SPARQL UPDATE should start with one of {valid_update_starts}")
    
    # Dry run mode - validate without executing
    if dry_run:
        return BaseToolMixin.create_success_response({
            "dry_run": True,
            "validated_query": sparql,
            "explanation": explanation or "Dry run validation for SPARQL UPDATE operation"
        }, "Query validated successfully. Set dry_run=false to execute.")
    
    agent = await get_agent()
    
    # Execute against local volume (journal) with 30 second timeout
    start_time = datetime.now()
    timeout_seconds = 30
    
    try:
        result = await asyncio.wait_for(
            asyncio.get_event_loop().run_in_executor(
                None,
                lambda: agent.anzo_client.update_journal(sparql)
            ),
            timeout=timeout_seconds
        )
        execution_time = (datetime.now() - start_time).total_seconds()
        
    except asyncio.TimeoutError:
        execution_time = (datetime.now() - start_time).total_seconds()
        return BaseToolMixin.create_error_response(
            f"Update operation timed out after {timeout_seconds} seconds",
            details={
                "execution_time_seconds": execution_time,
                "sparql_query": sparql,
                "timeout_seconds": timeout_seconds
            }
        )
    
    return BaseToolMixin.create_success_response({
        "operation_type": "update",
        "execution_time_seconds": execution_time,
        "sparql_query": sparql,
        "explanation": explanation,
        "volume": "local (journal)"
    }, "Successfully executed SPARQL UPDATE operation against local volume")