//! PTY integration via agor-core.
//!
//! Bridges agor-core's PtyManager to alacritty_terminal's event loop.
//! Reads PTY output in a background thread, feeds it into the Term state machine,
//! and notifies GPUI to repaint.

use agor_core::pty::{PtyManager, PtyOptions};
use std::sync::{Arc, Mutex};

/// Manages a single PTY ↔ Terminal connection.
pub struct PtyBridge {
    pub pty_id: Option<String>,
    pty_manager: Arc<PtyManager>,
    /// Raw bytes received from PTY, buffered for the renderer to consume.
    pub output_buffer: Arc<Mutex<Vec<u8>>>,
}

impl PtyBridge {
    pub fn new(pty_manager: Arc<PtyManager>) -> Self {
        Self {
            pty_id: None,
            pty_manager,
            output_buffer: Arc::new(Mutex::new(Vec::with_capacity(8192))),
        }
    }

    /// Spawn a PTY process and start reading its output.
    pub fn spawn(&mut self, cwd: &str) -> Result<(), String> {
        let id = self.pty_manager.spawn(PtyOptions {
            shell: None,
            cwd: Some(cwd.to_string()),
            args: None,
            cols: Some(120),
            rows: Some(30),
        })?;
        self.pty_id = Some(id);
        // NOTE: In a full implementation, we would start a background thread here
        // that reads from the PTY master fd and pushes bytes into output_buffer.
        // The PtyManager currently handles reading internally and emits events via
        // EventSink. For the GPUI bridge, we would intercept those events in the
        // Backend::drain_events() loop and feed them here.
        Ok(())
    }

    /// Write user input to the PTY.
    pub fn write(&self, data: &str) -> Result<(), String> {
        if let Some(ref id) = self.pty_id {
            self.pty_manager
                .write(id, data)
                .map_err(|e| format!("PTY write error: {e}"))
        } else {
            Err("No PTY spawned".to_string())
        }
    }

    /// Resize the PTY.
    pub fn resize(&self, cols: u16, rows: u16) -> Result<(), String> {
        if let Some(ref id) = self.pty_id {
            self.pty_manager
                .resize(id, cols, rows)
                .map_err(|e| format!("PTY resize error: {e}"))
        } else {
            Err("No PTY spawned".to_string())
        }
    }

    /// Drain buffered output bytes (consumed by the renderer).
    pub fn drain_output(&self) -> Vec<u8> {
        let mut buf = self.output_buffer.lock().unwrap();
        let data = buf.clone();
        buf.clear();
        data
    }
}
