/// <reference types="node" />
import { existsSync, readdirSync, readFileSync } from 'node:fs'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'

const SRC = join(__dirname)
const PKG_ROOT = join(__dirname, '..')
const FORBIDDEN = [
  '@platform-modules/db',                         // no db handle in the browser
  '@platform-modules/commerce-orders/schema',     // server-only drizzle schema deep import
  'createOrder',                                  // server write orchestrator — never in the browser sibling
  'claimForCharge',                               // server money op
  'markPaid',                                     // server money op
  'failOrder',                                    // server state op
  'markUnfulfillable',                            // server state op
  'recordStep',                                   // server state op
  'pushSchema',                                   // server migration
  'drizzle-orm',                                  // no ORM in the browser
  'node:',                                        // no Node builtins in the browser bundle (tests excluded by the scanner)
]

function srcFiles(dir: string): string[] {
  return readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
    const p = join(dir, e.name)
    if (e.isDirectory()) return srcFiles(p)
    return /\.(ts|tsx)$/.test(e.name) && !/\.test\.(ts|tsx)$/.test(e.name) ? [p] : []
  })
}

function distOffenders(text: string, label: string): string[] {
  const offenders: string[] = []
  for (const token of FORBIDDEN) {
    if (text.includes(token)) offenders.push(`${label} → ${token}`)
  }
  return offenders
}

function scanForForbidden(files: string[]): string[] {
  const offenders: string[] = []
  for (const f of files) {
    const text = readFileSync(f, 'utf8')
    for (const line of text.split('\n')) {
      const trimmed = line.trim()
      if (!trimmed.startsWith('import') && !/\bfrom\s+['"]/.test(trimmed)) continue
      for (const token of FORBIDDEN) {
        if (line.includes(token)) offenders.push(`${f} → ${token}`)
      }
    }
  }
  return offenders
}

describe('no server-only imports leak into the browser sibling (§0.5 bundle guard)', () => {
  it('no src file imports db / server-only core ops / ORM / node builtins', () => {
    const offenders = scanForForbidden(srcFiles(SRC))
    expect(offenders, offenders.join('\n')).toEqual([])
  })

  it('built dist bundle carries no server-only token when dist is present', () => {
    const distJs = join(PKG_ROOT, 'dist', 'index.js')
    if (!existsSync(distJs)) return
    const js = readFileSync(distJs, 'utf8')
    const offenders = distOffenders(js, 'dist/index.js')
    expect(offenders, offenders.join('\n')).toEqual([])
  })
})
