import asyncio
from typing import Callable, Any, Optional
from functools import wraps
import queue
import threading


class BackgroundTaskQueue:
    """Background task queue for async operations"""
    
    def __init__(self, max_workers: int = 4):
        self.max_workers = max_workers
        self.task_queue = queue.Queue()
        self.results = {}
        self.workers = []
        self.running = False
    
    def start(self):
        """Start background workers"""
        if self.running:
            return
        
        self.running = True
        for _ in range(self.max_workers):
            worker = threading.Thread(target=self._worker, daemon=True)
            worker.start()
            self.workers.append(worker)
    
    def stop(self):
        """Stop background workers"""
        self.running = False
        for _ in range(self.max_workers):
            self.task_queue.put(None)
        
        for worker in self.workers:
            worker.join()
    
    def _worker(self):
        """Background worker thread"""
        while self.running:
            try:
                task = self.task_queue.get(timeout=1)
                if task is None:
                    break
                
                task_id, func, args, kwargs = task
                try:
                    result = func(*args, **kwargs)
                    self.results[task_id] = ('success', result)
                except Exception as e:
                    self.results[task_id] = ('error', str(e))
                
                self.task_queue.task_done()
            except queue.Empty:
                continue
    
    def submit(self, func: Callable, *args, **kwargs) -> str:
        """Submit a task to the queue"""
        import uuid
        task_id = str(uuid.uuid4())
        
        self.task_queue.put((task_id, func, args, kwargs))
        return task_id
    
    def get_result(self, task_id: str) -> Optional[tuple]:
        """Get result of a task"""
        return self.results.get(task_id)
    
    def is_complete(self, task_id: str) -> bool:
        """Check if task is complete"""
        return task_id in self.results


task_queue = BackgroundTaskQueue()


def background_task(func: Callable):
    """Decorator to run function as background task"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        if not task_queue.running:
            task_queue.start()
        
        return task_queue.submit(func, *args, **kwargs)
    
    return wrapper


class AsyncApp:
    """Async support for FeatherOS apps"""
    
    def __init__(self):
        self.loop = None
        self.tasks = {}
    
    def run_async(self, coro):
        """Run async coroutine"""
        if self.loop is None:
            self.loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self.loop)
        
        return self.loop.run_until_complete(coro)
    
    def create_task(self, coro):
        """Create async task"""
        if self.loop is None:
            self.loop = asyncio.new_event_loop()
            asyncio.set_event_loop(self.loop)
        
        task = self.loop.create_task(coro)
        import uuid
        task_id = str(uuid.uuid4())
        self.tasks[task_id] = task
        return task_id
    
    async def gather(self, *coros):
        """Gather multiple coroutines"""
        return await asyncio.gather(*coros)


async_app = AsyncApp()
