import { describe, it, expect } from 'vitest'
import { highlightC } from '../utils/codeUtils.js'

describe('highlightC', () => {
  it('should highlight keywords', () => {
    const result = highlightC('int main()')
    expect(result).toContain('<span class="hl-keyword">int</span>')
    expect(result).toContain('<span class="hl-keyword">main</span>')
  })

  it('should highlight single-line comments', () => {
    const result = highlightC('// this is a comment')
    expect(result).toContain('<span class="hl-comment">')
    expect(result).toContain('// this is a comment')
  })

  it('should highlight multi-line comments', () => {
    const result = highlightC('/* multi\nline */')
    expect(result).toContain('<span class="hl-comment">')
    expect(result).toContain('/* multi')
    expect(result).toContain('line */')
  })

  it('should highlight string literals', () => {
    const result = highlightC('printf("hello world");')
    expect(result).toContain('<span class="hl-string">')
    expect(result).toContain('"hello world"')
  })

  it('should highlight char literals', () => {
    const result = highlightC("char c = 'A';")
    expect(result).toContain("<span class=\"hl-string\">'A'</span>")
  })

  it('should highlight numbers', () => {
    const result = highlightC('int x = 42;')
    expect(result).toContain('<span class="hl-number">42</span>')
  })

  it('should highlight float numbers', () => {
    const result = highlightC('float f = 3.14;')
    expect(result).toContain('<span class="hl-number">3.14</span>')
  })

  it('should highlight preprocessor directives', () => {
    const result = highlightC('#include <stdio.h>')
    expect(result).toContain('<span class="hl-preprocessor">')
    expect(result).toContain('#include &lt;stdio.h&gt;')
  })

  it('should NOT produce nested broken HTML tags', () => {
    const result = highlightC('#include <stdio.h>\nint main() {\n  printf("hello");\n}')
    // Should not contain any raw '<span' as visible text (it should be inside proper tags)
    expect(result).not.toContain('&lt;span')
    // Should not contain unescaped "<span" inside text content
    const stripped = result.replace(/<[^>]+>/g, '')
    expect(stripped).not.toContain('hl-keyword')
    expect(stripped).not.toContain('hl-comment')
    expect(stripped).not.toContain('hl-string')
    expect(stripped).not.toContain('hl-number')
  })

  it('should escape HTML in code content', () => {
    const result = highlightC('int x = a < b && b > c;')
    expect(result).toContain('&lt;')
    expect(result).toContain('&gt;')
    expect(result).not.toContain(' < ')
    expect(result).not.toContain(' > ')
  })

  it('should handle empty string', () => {
    expect(highlightC('')).toBe('')
  })

  it('should handle code with mixed content', () => {
    const code = `#include <stdio.h>
// main function
int main() {
  printf("Hello, World!\\n");
  return 0;
}`
    const result = highlightC(code)
    expect(result).toContain('hl-preprocessor')
    expect(result).toContain('hl-comment')
    expect(result).toContain('hl-keyword')
    expect(result).toContain('hl-string')
    expect(result).toContain('hl-number')
  })
})
