"""
AcreetionOS GUI Server.

Provides a Flask-based web interface for the Arch Linux installer, 
allowing users to configure and monitor their installation from a browser.
"""

import os
import json
import threading
from pathlib import Path
from flask import Flask, jsonify, request, send_from_directory

# Backend imports
from archinstall.lib.hardware import SysInfo
from archinstall.lib.args import ArchConfig, Arguments, arch_config_handler
from archinstall.lib.installer import Installer
from archinstall.lib.disk.filesystem import FilesystemHandler
from archinstall.lib.mirrors import MirrorListHandler
from archinstall.lib.authentication.authentication_handler import AuthenticationHandler
from archinstall.lib.applications.application_handler import ApplicationHandler
from archinstall.scripts.guided import perform_installation
from archinstall.lib.disk.device_handler import device_handler
from archinstall.lib.output import logger

# Acreetion-specific imports
from archinstall.acreetion.config_mapping import gui_config_to_arch_config

# Flask configuration - locating the static folder relative to this file
STATIC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
app = Flask(__name__, static_folder=STATIC_PATH, static_url_path='')

# Global log queue to be consumed by the frontend
installation_logs = []

def log_collector(message, *args, **kwargs):
    """
    Capture archinstall log messages into a global memory buffer for web display.
    """
    global installation_logs
    installation_logs.append(str(message))
    if len(installation_logs) > 1000:
        installation_logs.pop(0)

logger.info = log_collector
logger.debug = log_collector
logger.error = log_collector
logger.warn = log_collector

@app.route('/')
def index():
    """Serves the main GUI application."""
    return send_from_directory(STATIC_PATH, 'index.html')

@app.route('/api/disks', methods=['GET'])
def get_disks():
    """
    Returns a list of local block devices available for installation.
    Filters out loop devices and disks smaller than 1GB.
    """
    try:
        disks = SysInfo._disk_devices()
        disk_list = []
        for disk_name, disk_info in disks.items():
            if 'loop' in disk_name or disk_info.get('size', 0) < 1024 * 1024 * 1024:
                continue
            disk_list.append({
                'path': disk_name,
                'model': disk_info.get('model', 'Unknown Model'),
                'size': f"{disk_info.get('size', 0) / (1024**3):.2f} GB"
            })
        return jsonify({'disks': disk_list})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route('/api/logs', methods=['GET'])
def get_logs():
    """Returns the current buffered log messages."""
    return jsonify({'logs': installation_logs})

def perform_installation_task(arch_config):
    """
    Background worker that executes the actual Arch Linux installation process.
    """
    try:
        mirror_list_handler = MirrorListHandler(offline=False)
        fs_handler = FilesystemHandler(arch_config.disk_config)
        fs_handler.perform_filesystem_operations()
        
        arch_config_handler.config = arch_config
        arch_config_handler.args = Arguments(mountpoint=Path('/mnt'), silent=True)
        
        perform_installation(
            mountpoint=Path('/mnt'),
            mirror_list_handler=mirror_list_handler,
            auth_handler=AuthenticationHandler(),
            application_handler=ApplicationHandler()
        )
    except Exception as e:
        print(f"Installation failed: {e}")

@app.route('/api/install', methods=['POST'])
def start_install():
    """
    API endpoint to initiate the installation process.
    Receives JSON configuration and starts a background thread.
    """
    gui_config = request.json
    try:
        arch_config = gui_config_to_arch_config(gui_config)
        thread = threading.Thread(target=perform_installation_task, args=(arch_config,))
        thread.start()
        return jsonify({'success': True, 'message': 'Installation started'})
    except Exception as e:
        return jsonify({'error': str(e)}), 500

def run_server():
    """Starts the Flask development server on the local interface."""
    print(f"AcreetionOS GUI Server starting on http://127.0.0.1:5000")
    print(f"Static path: {STATIC_PATH}")
    app.run(host='127.0.0.1', port=5000, debug=True, use_reloader=False)

if __name__ == '__main__':
    run_server()
