import { describe, it, expect } from 'vitest'
import { createLineBuffer } from '../src/main/lib/lineBuffer'

/** Collect every line a buffer emits, for assertions. */
function collect(): { lines: string[]; buf: ReturnType<typeof createLineBuffer> } {
  const lines: string[] = []
  const buf = createLineBuffer((l) => lines.push(l))
  return { lines, buf }
}

describe('createLineBuffer', () => {
  it('emits one line per newline, without the newline', () => {
    const { lines, buf } = collect()
    buf.push('a\nb\nc\n')
    expect(lines).toEqual(['a', 'b', 'c'])
  })

  it('holds a partial line until its newline arrives across chunks', () => {
    const { lines, buf } = collect()
    buf.push('hel')
    expect(lines).toEqual([])
    buf.push('lo\nwor')
    expect(lines).toEqual(['hello'])
    buf.push('ld\n')
    expect(lines).toEqual(['hello', 'world'])
  })

  it('strips a trailing CR so CRLF streams split cleanly', () => {
    const { lines, buf } = collect()
    buf.push('one\r\ntwo\r\n')
    expect(lines).toEqual(['one', 'two'])
  })

  it('flush emits a trailing partial line that never saw a newline', () => {
    const { lines, buf } = collect()
    buf.push('no newline here')
    expect(lines).toEqual([])
    buf.flush()
    expect(lines).toEqual(['no newline here'])
  })

  it('flush is a no-op when the buffer is empty (e.g. stream ended on a newline)', () => {
    const { lines, buf } = collect()
    buf.push('done\n')
    buf.flush()
    buf.flush()
    expect(lines).toEqual(['done'])
  })

  it('preserves empty lines between consecutive newlines', () => {
    const { lines, buf } = collect()
    buf.push('a\n\nb\n')
    expect(lines).toEqual(['a', '', 'b'])
  })

  it('splits a multi-line chunk that arrives all at once', () => {
    const { lines, buf } = collect()
    buf.push('1\n2\n3')
    expect(lines).toEqual(['1', '2'])
    buf.flush()
    expect(lines).toEqual(['1', '2', '3'])
  })
})
