package wang.yaojia.webterm.terminalview

import android.content.Context
import android.view.KeyEvent
import com.termux.terminal.TerminalEmulator
import com.termux.view.TerminalView

/**
 * The on-screen terminal seam — a COMPOSITION wrapper around Termux's stock [TerminalView].
 *
 * ### Deviation from plan §6.1 (recorded): composition, not subclass
 * §6.1 says "the Termux `TerminalView` is subclassed only to expose an onKeyCommand outlet + install
 * the key-bar." But at the pinned v0.118.0, `com.termux.view.TerminalView` is declared
 * `public final class` — it CANNOT be subclassed (verified: the Kotlin compiler rejects
 * `: TerminalView(...)` with "This type is final"). We therefore WRAP a stock instance and bind our
 * forked emulator through its PUBLIC `mEmulator` field instead of via `attachSession(TerminalSession)`
 * (there is no `TerminalSession` to fork — it too is `final`, and forking a process is exactly what we
 * must not do). Glyph rendering, cursor, selection, IME and scroll stay 100% stock — the wrapped view
 * renders unchanged; we only redirect where the emulator comes from and where input goes.
 *
 * The [terminalView] is what A21 puts in the Compose tree (`AndroidView { remote.terminalView }`); the
 * key-bar / hardware-chord layer (A17) installs its handler through [onKeyCommand] (delivered via a
 * `TerminalViewClient` A17 sets on [terminalView]) and reads [onViewSizeChanged] for the resize path.
 *
 * DEVICE-QA (plan §7): rendering, IME, selection, link taps, and the real font-metric→grid resize
 * (`TerminalRenderer.mFontWidth` is package-private → measured on-device and fed to [TerminalGridMath])
 * are verified on a device, not here. This class only has to compile and offer the binding seam.
 */
public class RemoteTerminalView(context: Context) {

    /** The stock, final Termux view. Added to the Compose tree by A21; rendering is entirely its own. */
    public val terminalView: TerminalView = TerminalView(context, null)

    /** The forked session backing this view. Set by [RemoteTerminalSession.attachView]. */
    public var session: RemoteTerminalSession? = null

    /**
     * Hardware-key outlet (A17 install point). A17 wires this into a `TerminalViewClient` set on
     * [terminalView]; returning true consumes the event, otherwise arrows/Enter/Tab should be resolved
     * via [RemoteTerminalSession.keyBytes] so DECCKM still emits `ESC O A` (plan §6.3).
     */
    public var onKeyCommand: ((keyCode: Int, event: KeyEvent) -> Boolean)? = null

    /** Layout-change outlet (A17/A21 install point) — wires real font metrics into the resize path. */
    public var onViewSizeChanged: ((widthPx: Int, heightPx: Int) -> Unit)? = null

    /** Point the stock renderer at the forked emulator (bypasses the process-forking `attachSession`). */
    public fun bindEmulator(emulator: TerminalEmulator) {
        terminalView.mEmulator = emulator
    }

    /** Invalidate/redraw the stock view for the current emulator state (posted on the main thread). */
    public fun requestScreenUpdate() {
        terminalView.onScreenUpdated()
    }
}
