import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { resolveStaticWebsiteConfig, shouldServeSpaFallback } from '../static-site'

const tempRoots: string[] = []

function makeTempRoot() {
  const root = mkdtempSync(path.join(os.tmpdir(), 'hypertwist-static-site-'))
  tempRoots.push(root)
  return root
}

afterEach(() => {
  while (tempRoots.length > 0) {
    const root = tempRoots.pop()
    if (root) {
      rmSync(root, { recursive: true, force: true })
    }
  }
})

describe('resolveStaticWebsiteConfig', () => {
  it('auto-enables same-origin static serving when website/dist/index.html exists', () => {
    const root = makeTempRoot()
    const distDir = path.join(root, 'dist')
    mkdirSync(distDir, { recursive: true })
    writeFileSync(path.join(distDir, 'index.html'), '<html></html>', 'utf8')

    const config = resolveStaticWebsiteConfig({
      cwd: path.join(root, 'server'),
      websiteDistPath: '../dist',
    })

    expect(config.enabled).toBe(true)
    expect(config.reason).toBe('auto_found')
    expect(config.indexHtmlPath).toBe(path.join(distDir, 'index.html'))
  })

  it('stays disabled in auto mode when no built website output is present', () => {
    const root = makeTempRoot()

    const config = resolveStaticWebsiteConfig({
      cwd: path.join(root, 'server'),
      websiteDistPath: '../dist',
    })

    expect(config.enabled).toBe(false)
    expect(config.reason).toBe('auto_missing')
  })

  it('reports a forced-missing posture when static serving is explicitly requested without a build', () => {
    const root = makeTempRoot()

    const config = resolveStaticWebsiteConfig({
      cwd: path.join(root, 'server'),
      websiteDistPath: '../dist',
      serveStaticWebsite: 'true',
    })

    expect(config.enabled).toBe(false)
    expect(config.reason).toBe('forced_missing')
  })
})

describe('shouldServeSpaFallback', () => {
  it('accepts application routes and marketing paths', () => {
    expect(shouldServeSpaFallback('/')).toBe(true)
    expect(shouldServeSpaFallback('/about')).toBe(true)
    expect(shouldServeSpaFallback('/app/downloads')).toBe(true)
    expect(shouldServeSpaFallback('/login')).toBe(true)
  })

  it('rejects api, auth, health, and static-asset requests', () => {
    expect(shouldServeSpaFallback('/health')).toBe(false)
    expect(shouldServeSpaFallback('/api/auth/me')).toBe(false)
    expect(shouldServeSpaFallback('/auth/session/refresh')).toBe(false)
    expect(shouldServeSpaFallback('/assets/index-abc123.js')).toBe(false)
    expect(shouldServeSpaFallback('/favicon.ico')).toBe(false)
  })
})
