/**
 * neutralizeFormula tests — financial-statements (wave-13).
 *
 * Verifies formula-injection neutralization for XLSX and CSV exports.
 */
import { describe, it, expect } from 'vitest'
import { neutralizeFormula } from '../src/sanitize'
import { writeCsv } from '../src/csv'
import type { ExportSheet } from '../src/types'

describe('neutralizeFormula', () => {
  it('prefixes = with apostrophe', () => {
    expect(neutralizeFormula('=SUM(A1:A9)')).toBe("'=SUM(A1:A9)")
  })

  it('prefixes + with apostrophe', () => {
    expect(neutralizeFormula('+cmd')).toBe("'+cmd")
  })

  it('prefixes - with apostrophe', () => {
    expect(neutralizeFormula('-1+1')).toBe("'-1+1")
  })

  it('prefixes @ with apostrophe', () => {
    expect(neutralizeFormula('@SUM')).toBe("'@SUM")
  })

  it('prefixes tab with apostrophe', () => {
    expect(neutralizeFormula('\tSUM')).toBe("'\tSUM")
  })

  it('prefixes carriage-return with apostrophe', () => {
    expect(neutralizeFormula('\rSUM')).toBe("'\rSUM")
  })

  it('does not modify benign strings', () => {
    expect(neutralizeFormula('Hello World')).toBe('Hello World')
    expect(neutralizeFormula('100.00')).toBe('100.00')
    expect(neutralizeFormula('')).toBe('')
    expect(neutralizeFormula('שלום')).toBe('שלום')
  })

  it('does not modify numbers in middle', () => {
    expect(neutralizeFormula('total=100')).toBe('total=100')
  })
})

describe('writeCsv formula-injection neutralization', () => {
  const sheet: ExportSheet = {
    name: 'Test',
    columns: [
      { key: 'label', header: 'Label' },
      { key: 'value', header: 'Value' },
    ],
    rows: [
      { label: '=SUM(A1:A9)', value: 100 },
      { label: 'Normal text', value: 200 },
      { label: '+exploit', value: 0 },
    ],
  }

  it('neutralizes formula triggers in CSV output', () => {
    const bytes = writeCsv({ sheet })
    // Skip BOM (3 bytes) and decode
    const csv = new TextDecoder().decode(bytes.slice(3))
    expect(csv).toContain("'=SUM(A1:A9)")
    expect(csv).toContain("'+exploit")
    expect(csv).toContain('Normal text')
  })

  it('emits UTF-8 BOM by default', () => {
    const bytes = writeCsv({ sheet })
    expect(bytes[0]).toBe(0xef)
    expect(bytes[1]).toBe(0xbb)
    expect(bytes[2]).toBe(0xbf)
  })
})
