import { ParsedFile, severityRank, confidenceRank } from '../parsed-file'

describe('ParsedFile', () => {
  const sampleContent = 'line0\nline1\nline2\nline3\nline4'
  const parsed = new ParsedFile(sampleContent, 'test.ts')

  describe('lines', () => {
    it('splits content into lines', () => {
      expect(parsed.lines).toEqual(['line0', 'line1', 'line2', 'line3', 'line4'])
    })

    it('caches the result (returns same reference)', () => {
      expect(parsed.lines).toBe(parsed.lines)
    })

    it('handles empty content', () => {
      const empty = new ParsedFile('', 'empty.ts')
      expect(empty.lines).toEqual([''])
      expect(empty.lineCount).toBe(1)
    })
  })

  describe('lineCount', () => {
    it('returns the number of lines', () => {
      expect(parsed.lineCount).toBe(5)
    })
  })

  describe('line()', () => {
    it('returns the correct line by 0-based index', () => {
      expect(parsed.line(0)).toBe('line0')
      expect(parsed.line(2)).toBe('line2')
      expect(parsed.line(4)).toBe('line4')
    })

    it('returns empty string for negative index', () => {
      expect(parsed.line(-1)).toBe('')
    })

    it('returns empty string for out-of-bounds index', () => {
      expect(parsed.line(5)).toBe('')
      expect(parsed.line(100)).toBe('')
    })
  })

  describe('getSurroundingLines()', () => {
    it('returns lines within window', () => {
      const result = parsed.getSurroundingLines(2, 1)
      expect(result.lines).toEqual(['line1', 'line2', 'line3'])
      expect(result.startIndex).toBe(1)
      expect(result.endIndex).toBe(3)
      expect(result.text).toBe('line1\nline2\nline3')
    })

    it('clamps to start of file', () => {
      const result = parsed.getSurroundingLines(0, 3)
      expect(result.startIndex).toBe(0)
      expect(result.lines[0]).toBe('line0')
    })

    it('clamps to end of file', () => {
      const result = parsed.getSurroundingLines(4, 3)
      expect(result.endIndex).toBe(4)
      expect(result.lines[result.lines.length - 1]).toBe('line4')
    })

    it('handles window larger than file', () => {
      const result = parsed.getSurroundingLines(2, 100)
      expect(result.startIndex).toBe(0)
      expect(result.endIndex).toBe(4)
      expect(result.lines.length).toBe(5)
    })
  })

  describe('getLineRange()', () => {
    it('returns joined lines for valid range', () => {
      expect(parsed.getLineRange(1, 3)).toBe('line1\nline2\nline3')
    })

    it('clamps to bounds', () => {
      expect(parsed.getLineRange(-2, 1)).toBe('line0\nline1')
      expect(parsed.getLineRange(3, 100)).toBe('line3\nline4')
    })

    it('returns empty for inverted range', () => {
      expect(parsed.getLineRange(3, 1)).toBe('')
    })
  })

  describe('static from()', () => {
    it('creates from ScanFile-like object', () => {
      const file = { content: 'hello\nworld', path: 'foo.ts' }
      const pf = ParsedFile.from(file)
      expect(pf.content).toBe('hello\nworld')
      expect(pf.filePath).toBe('foo.ts')
      expect(pf.lines).toEqual(['hello', 'world'])
    })
  })
})

describe('severityRank', () => {
  it('ranks critical > high > medium > low > info', () => {
    expect(severityRank('critical')).toBeGreaterThan(severityRank('high'))
    expect(severityRank('high')).toBeGreaterThan(severityRank('medium'))
    expect(severityRank('medium')).toBeGreaterThan(severityRank('low'))
    expect(severityRank('low')).toBeGreaterThan(severityRank('info'))
  })

  it('returns 0 for unknown severity', () => {
    expect(severityRank('unknown')).toBe(0)
    expect(severityRank('')).toBe(0)
  })
})

describe('confidenceRank', () => {
  it('ranks high > medium > low', () => {
    expect(confidenceRank('high')).toBeGreaterThan(confidenceRank('medium'))
    expect(confidenceRank('medium')).toBeGreaterThan(confidenceRank('low'))
  })

  it('returns 0 for unknown confidence', () => {
    expect(confidenceRank('unknown')).toBe(0)
  })
})
