import os
import uuid
import subprocess
import shlex

# Directory for logs
LOG_DIR = os.path.join(os.path.dirname(__file__), 'instance/logs')
if not os.path.exists(LOG_DIR):
    os.makedirs(LOG_DIR, exist_ok=True)

def start_task(command_str):
    """
    Starts a background task in a screen session.
    Returns task_id.
    """
    if isinstance(command_str, (list, tuple)):
        safe_command = ' '.join(shlex.quote(str(part)) for part in command_str)
    elif isinstance(command_str, str):
        safe_command = command_str
    else:
        return None, "Invalid command type"

    task_id = str(uuid.uuid4())
    log_file = os.path.join(LOG_DIR, f"{task_id}.log")
    
    # Ensure log file exists
    open(log_file, 'w').close()
    
    # Construct Screen Command
    # -d -m: Detach and mode (start in background)
    # -S: Session name
    # -L -Logfile: Log output
    # bash -c: Run command and append exit code
    
    # We wrap the command to capture exit code and ensure non-interactive apt
    # Redirect output directly to log file to avoid Screen buffering issues
    # Use unbuffered output where possible? apt-get is usually fine.
    wrapped_cmd = (
        f"(export DEBIAN_FRONTEND=noninteractive; {safe_command}; "
        f"echo 'EXIT_CODE:'$?) > {shlex.quote(log_file)} 2>&1"
    )
    
    # Safety: shlex.quote the wrapped command for the screen invocation
    # But wait, screen args are weird. 
    # screen -d -m -S name bash -c "cmd"
    
    screen_cmd = [
        "screen", "-d", "-m", 
        "-S", f"limristem_web_task_{task_id}",
        "bash", "-c", wrapped_cmd
    ]
    
    try:
        # Pass current environment but ensure TERM is set for screen to work headless
        env = os.environ.copy()
        env['TERM'] = 'xterm'
        subprocess.run(screen_cmd, check=True, env=env)
        return task_id, None
    except Exception as e:
        return None, str(e)

def get_task_log(task_id):
    """Returns (content, is_finished, exit_code)."""
    log_file = os.path.join(LOG_DIR, f"{task_id}.log")
    if not os.path.exists(log_file):
        return "Log not found", True, -1
        
    try:
        with open(log_file, 'rb') as f:
            f.seek(0, os.SEEK_END)
            size = f.tell()
            f.seek(max(size - 200000, 0))
            content = f.read().decode('utf-8', errors='replace')
            
        is_finished = False
        exit_code = None
        
        if "EXIT_CODE:" in content:
            is_finished = True
            # Extract code (last occurrence)
            parts = content.split("EXIT_CODE:")
            try:
                code_str = parts[-1].strip().split('\n')[0]
                exit_code = int(code_str)
            except:
                pass
                
        return content, is_finished, exit_code
    except Exception as e:
        return str(e), True, -1
