import { describe, it, expect } from 'vitest'
import { createMockPty } from './mock-pty'

describe('createMockPty', () => {
  it('emitData triggers all onData listeners', () => {
    const pty = createMockPty()
    const listener1Results: string[] = []
    const listener2Results: string[] = []

    pty.onData((data) => {
      listener1Results.push(data)
    })
    pty.onData((data) => {
      listener2Results.push(data)
    })

    pty.emitData('hello')
    pty.emitData(' world')

    expect(listener1Results).toEqual(['hello', ' world'])
    expect(listener2Results).toEqual(['hello', ' world'])
  })

  it('onData returns a disposable that unsubscribes', () => {
    const pty = createMockPty()
    const results: string[] = []

    const disposable = pty.onData((data) => {
      results.push(data)
    })

    pty.emitData('first')
    disposable.dispose()
    pty.emitData('second')

    expect(results).toEqual(['first'])
  })

  it('records write calls', () => {
    const pty = createMockPty()

    pty.write('input 1')
    pty.write('input 2')

    expect(pty.writes).toEqual(['input 1', 'input 2'])
  })

  it('records resize calls', () => {
    const pty = createMockPty()

    pty.resize(100, 50)
    pty.resize(120, 60)

    expect(pty.resizes).toEqual([
      { cols: 100, rows: 50 },
      { cols: 120, rows: 60 },
    ])
  })

  it('emitExit triggers onExit listeners', () => {
    const pty = createMockPty()
    const results: Array<{ exitCode: number; signal?: number }> = []

    pty.onExit((event) => {
      results.push(event)
    })

    pty.emitExit(0)
    pty.emitExit(1, 9)

    expect(results).toEqual([
      { exitCode: 0 },
      { exitCode: 1, signal: 9 },
    ])
  })

  it('onExit returns a disposable that unsubscribes', () => {
    const pty = createMockPty()
    const results: Array<{ exitCode: number; signal?: number }> = []

    const disposable = pty.onExit((event) => {
      results.push(event)
    })

    pty.emitExit(0)
    disposable.dispose()
    pty.emitExit(1)

    expect(results).toEqual([{ exitCode: 0 }])
  })

  it('kill marks killed flag', () => {
    const pty = createMockPty()

    expect(pty.killed).toBe(false)
    pty.kill()
    expect(pty.killed).toBe(true)
  })

  it('kill can accept an optional signal', () => {
    const pty = createMockPty()

    pty.kill('SIGTERM')
    expect(pty.killed).toBe(true)
  })

  it('has IPty interface properties', () => {
    const pty = createMockPty()

    expect(typeof pty.pid).toBe('number')
    expect(typeof pty.cols).toBe('number')
    expect(typeof pty.rows).toBe('number')
    expect(typeof pty.onData).toBe('function')
    expect(typeof pty.onExit).toBe('function')
    expect(typeof pty.write).toBe('function')
    expect(typeof pty.resize).toBe('function')
    expect(typeof pty.kill).toBe('function')
  })
})
