"""SQLite service for local database access through the tunnel.

This service provides an HTTP API that the backend can call through the tunnel
to execute queries on local SQLite database files.
"""

import asyncio
import logging
import sqlite3
from typing import Optional
from aiohttp import web

logger = logging.getLogger(__name__)


class SQLiteService:
    """Manages local SQLite database access via HTTP API."""
    
    def __init__(self, port: int = 9999):
        self.port = port
        self.app: Optional[web.Application] = None
        self.runner: Optional[web.AppRunner] = None
        self.running = False
    
    async def start(self):
        """Start the SQLite HTTP service."""
        if self.running:
            logger.warning("SQLite service already running")
            return
        
        try:
            logger.info(f"Starting SQLite service on localhost:{self.port}")
            
            self.app = web.Application()
            self.app.router.add_post('/query', self.handle_query)
            
            self.runner = web.AppRunner(self.app)
            await self.runner.setup()
            site = web.TCPSite(self.runner, 'localhost', self.port)
            await site.start()
            
            self.running = True
            logger.info(f"✅ SQLite service started on localhost:{self.port}")
            
        except Exception as e:
            logger.error(f"Failed to start SQLite service: {e}")
            await self.cleanup()
            raise
    
    async def handle_query(self, request: web.Request) -> web.Response:
        """Execute a SQLite query on a local database file."""
        try:
            data = await request.json()
            
            db_path = data.get('database_path')
            query = data.get('query')
            params = data.get('params', [])
            read_only = data.get('read_only', False)
            
            if not db_path:
                return web.json_response({
                    "success": False,
                    "error": "database_path is required"
                }, status=400)
            
            if not query:
                return web.json_response({
                    "success": False,
                    "error": "query is required"
                }, status=400)
            
            # Security: Only allow absolute paths, no relative paths
            if not db_path.startswith('/'):
                return web.json_response({
                    "success": False,
                    "error": "Only absolute file paths are allowed"
                }, status=400)
            
            logger.info(f"Executing query on {db_path}: {query[:100]}...")
            
            # Connect to local SQLite file
            if read_only:
                conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
            else:
                conn = sqlite3.connect(db_path)
            
            try:
                cursor = conn.execute(query, params)
                
                # Check if it's a SELECT query
                if query.strip().upper().startswith('SELECT') or query.strip().upper().startswith('PRAGMA'):
                    results = cursor.fetchall()
                    columns = [desc[0] for desc in cursor.description] if cursor.description else []
                else:
                    # For INSERT, UPDATE, DELETE, etc.
                    conn.commit()
                    results = []
                    columns = []
                
                rowcount = cursor.rowcount
                
                return web.json_response({
                    "success": True,
                    "rows": results,
                    "columns": columns,
                    "rowcount": rowcount,
                })
            
            finally:
                conn.close()
        
        except sqlite3.Error as e:
            logger.error(f"SQLite error: {e}")
            return web.json_response({
                "success": False,
                "error": f"SQLite error: {str(e)}"
            }, status=400)
        
        except Exception as e:
            logger.error(f"Error handling query: {e}")
            return web.json_response({
                "success": False,
                "error": str(e)
            }, status=500)
    
    async def stop(self):
        """Stop the SQLite service."""
        if not self.running:
            logger.warning("SQLite service not running")
            return
        
        logger.info("Stopping SQLite service...")
        await self.cleanup()
        logger.info("✅ SQLite service stopped")
    
    async def cleanup(self):
        """Clean up resources."""
        self.running = False
        
        if self.runner:
            try:
                await self.runner.cleanup()
            except Exception as e:
                logger.error(f"Error cleaning up runner: {e}")
            self.runner = None
        
        self.app = None
    
    def get_status(self) -> dict:
        """Get current SQLite service status."""
        return {
            "enabled": self.running,
            "port": self.port,
        }


