import { describe, expect, it } from 'vitest'

import {
  appendDirective,
  makeDirectiveEntry,
  parseDirectiveLog,
  serializeDirective,
  toDirectiveInput,
} from './record-directive-v0.js'

describe('toDirectiveInput', () => {
  it('keeps a valid kind + target and drops an empty target', () => {
    const input = toDirectiveInput({ kind: 'reprioritize', quote: 'pilots first', target: { issue: 87 }, rationale: 'blocked' })
    expect(input).toEqual({ kind: 'reprioritize', quote: 'pilots first', target: { issue: 87 }, params: undefined, rationale: 'blocked' })
    expect(toDirectiveInput({ kind: 'note', quote: 'x', target: {} }).target).toBeUndefined()
  })

  it('falls back to note for an unknown kind', () => {
    expect(toDirectiveInput({ kind: 'nonsense', quote: 'hmm' }).kind).toBe('note')
  })
})

describe('serialize + parse round-trip', () => {
  const entry = makeDirectiveEntry(
    { kind: 'reprioritize', quote: 'pilots come first', target: { issue: 87 } },
    'id-1',
    '2026-02-01T09:00:00Z',
  )

  it('serializes to one JSON line', () => {
    const line = serializeDirective(entry)
    expect(line).not.toContain('\n')
    expect(JSON.parse(line)).toMatchObject({ id: 'id-1', kind: 'reprioritize', status: 'accepted' })
  })

  it('parses a log, orders by ts, and assigns a 1-based seq', () => {
    const a = serializeDirective(makeDirectiveEntry({ kind: 'note', quote: 'later' }, 'b', '2026-02-02T00:00:00Z'))
    const b = serializeDirective(makeDirectiveEntry({ kind: 'note', quote: 'earlier' }, 'a', '2026-02-01T00:00:00Z'))
    const records = parseDirectiveLog(`${a}\n${b}\n`)
    expect(records.map((r) => r.quote)).toEqual(['earlier', 'later'])
    expect(records.map((r) => r.seq)).toEqual([1, 2])
  })

  it('skips blank and corrupt lines without losing the rest', () => {
    const good = serializeDirective(entry)
    const records = parseDirectiveLog(`\n{not json\n${good}\n\n`)
    expect(records).toHaveLength(1)
    expect(records[0].id).toBe('id-1')
  })
})

describe('appendDirective', () => {
  it('concatenates a newline-terminated entry, normalizing a missing trailing newline', () => {
    const e1 = makeDirectiveEntry({ kind: 'note', quote: 'one' }, 'i1', '2026-01-01T00:00:00Z')
    const e2 = makeDirectiveEntry({ kind: 'note', quote: 'two' }, 'i2', '2026-01-02T00:00:00Z')
    let log = appendDirective('', e1)
    log = appendDirective(log, e2)
    expect(parseDirectiveLog(log).map((r) => r.quote)).toEqual(['one', 'two'])
    expect(log.endsWith('\n')).toBe(true)
  })

  it('handles existing text without a trailing newline', () => {
    const e = makeDirectiveEntry({ kind: 'note', quote: 'x' }, 'i', '2026-01-01T00:00:00Z')
    expect(appendDirective('{"id":"prev","ts":"2025-01-01T00:00:00Z"}', e).split('\n').filter(Boolean)).toHaveLength(2)
  })
})
