import { describe, it, expect } from 'vitest'
import { cleanError, describeDownloadError, stderrDetail } from '../src/main/log'

describe('cleanError', () => {
  it('returns the last ERROR line, stripped of its prefix', () => {
    const stderr = [
      '[youtube] gHiZA4O5PQM: Downloading webpage',
      'ERROR: [youtube] gHiZA4O5PQM: Video unavailable. This video is private'
    ].join('\n')
    expect(cleanError(stderr)).toBe(
      '[youtube] gHiZA4O5PQM: Video unavailable. This video is private'
    )
  })

  it('falls back to the last line when nothing matches /error/', () => {
    expect(cleanError('one\ntwo\nthree')).toBe('three')
  })

  it('returns empty string for blank stderr', () => {
    expect(cleanError('')).toBe('')
  })
})

describe('describeDownloadError', () => {
  // A real non-verbose SponsorBlock-remove failure: yt-dlp emits only the
  // [ModifyChapters] step lines and the bare wrapper error.
  const modifyChaptersFailure = [
    '[info] qkUTB65OfAc: Downloading 1 format(s): 137+251',
    '[SponsorBlock] Found 1 segments in the SponsorBlock database',
    '[Merger] Merging formats into "video.mp4"',
    'Deleting original file video.f251.webm (pass -k to keep)',
    'Deleting original file video.f137.mp4 (pass -k to keep)',
    '[ModifyChapters] Re-encoding "video.mp4" with appropriate keyframes',
    '[ModifyChapters] Removing chapters from video.mp4',
    'ERROR: Postprocessing: Conversion failed!'
  ].join('\n')

  it('names the failing post-processing step for the bare "Conversion failed!" wrapper', () => {
    const msg = describeDownloadError(modifyChaptersFailure)
    expect(msg.startsWith('Postprocessing: Conversion failed!')).toBe(true)
    expect(msg).toContain('ModifyChapters')
  })

  it('skips [download] progress and "Deleting original file" bookkeeping as context', () => {
    const msg = describeDownloadError(modifyChaptersFailure)
    expect(msg).not.toContain('Deleting original file')
    expect(msg).not.toMatch(/\[download\]/)
  })

  it('leaves a self-explanatory (non-postprocessing) error unchanged', () => {
    const stderr = [
      '[youtube] gHiZA4O5PQM: Downloading webpage',
      'ERROR: [youtube] gHiZA4O5PQM: Video unavailable. This video is private'
    ].join('\n')
    expect(describeDownloadError(stderr)).toBe(cleanError(stderr))
  })

  it('does not echo the headline back as its own context', () => {
    const stderr = 'ERROR: Postprocessing: Conversion failed!'
    expect(describeDownloadError(stderr)).toBe('Postprocessing: Conversion failed!')
  })

  it('caps an over-long context line', () => {
    const longPath = 'x'.repeat(400)
    const stderr = [
      `[ModifyChapters] Re-encoding "${longPath}" with appropriate keyframes`,
      'ERROR: Postprocessing: Conversion failed!'
    ].join('\n')
    const msg = describeDownloadError(stderr)
    expect(msg).toContain('…')
    // headline + separator + a single capped context line, nowhere near 400 chars.
    expect(msg.length).toBeLessThan(300)
  })

  it('returns empty string for blank stderr (falls through to the caller fallback)', () => {
    expect(describeDownloadError('')).toBe('')
  })
})

describe('stderrDetail', () => {
  it('keeps the full non-noise transcript for the Diagnostics "Show details" expander', () => {
    const stderr = [
      '[info] qkUTB65OfAc: Downloading 1 format(s): 137+251',
      '[SponsorBlock] Found 1 segments in the SponsorBlock database',
      '[ModifyChapters] Re-encoding "video.mp4" with appropriate keyframes',
      'ERROR: Postprocessing: Conversion failed!'
    ].join('\n')
    const detail = stderrDetail(stderr)
    expect(detail).toContain('[SponsorBlock] Found 1 segments')
    expect(detail).toContain('[ModifyChapters] Re-encoding')
    expect(detail).toContain('ERROR: Postprocessing: Conversion failed!')
  })

  it('strips [download] progress ticks and "Deleting original file" bookkeeping', () => {
    const stderr = [
      '[download]  42.0% of   23.21MiB at   15.11MiB/s ETA 00:00',
      'Deleting original file video.f251.webm (pass -k to keep)',
      '[ModifyChapters] Re-encoding "video.mp4" with appropriate keyframes',
      'ERROR: Postprocessing: Conversion failed!'
    ].join('\n')
    const detail = stderrDetail(stderr)
    expect(detail).not.toMatch(/\[download\]/)
    expect(detail).not.toContain('Deleting original file')
  })

  it('returns undefined when there is nothing beyond a single headline', () => {
    expect(stderrDetail('ERROR: Postprocessing: Conversion failed!')).toBeUndefined()
  })

  it('returns undefined for blank stderr', () => {
    expect(stderrDetail('')).toBeUndefined()
  })
})
