import { test } from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

import { shellClass, SHELL_WIDTHS } from '../src/lib/pageShell.js'

// `PublicLayout`'s `shell` prop (MODULE_API.md §3.4, MODULE_API_VERSION 1.5.0).
// The component itself is .jsx and unreachable from this runner — there is no DOM
// here — so the rule lives in lib/pageShell.js and is asserted here, and the
// rendering is proved in a browser (MODULE_API.md §7.7), which is where the
// defect that produced this prop was found in the first place.

const HERE = path.dirname(fileURLToPath(import.meta.url))

test('no shell means no wrapper — the behaviour every page had before 1.5.0', () => {
  // null, not an empty string: PublicLayout branches on it to render `children`
  // bare, and '' would render a <div class=""> that changes core's nine pages.
  assert.equal(shellClass(undefined), null)
  assert.equal(shellClass(null), null)
  assert.equal(shellClass(''), null)
  assert.equal(shellClass(false), null)
})

test('each documented width maps to its theme.css class, plus page-body', () => {
  assert.equal(shellClass('narrow'), 'shell-narrow page-body')
  assert.equal(shellClass('mid'), 'shell-mid page-body')
  assert.equal(shellClass('wide'), 'shell-wide page-body')
})

test('page-body is always present — it is what pushes the footer down', () => {
  // `.page` is a flex column and `.page-body { flex: 1 }` is the only thing
  // filling it. A width class on its own centres the content and still lets the
  // footer ride up under it, which is half the reported defect and the half that
  // is easy to lose in a refactor.
  for (const w of SHELL_WIDTHS) {
    assert.match(shellClass(w), /\bpage-body\b/)
  }
})

test('an unknown width still renders a wrapper, at the narrow default', () => {
  // The value can arrive from a module built against a different version of this
  // list, so the failure mode has to be "wrong width" and never "no wrapper".
  assert.equal(shellClass('enormous'), 'shell-narrow page-body')
  assert.equal(shellClass(true), 'shell-narrow page-body')
  assert.equal(shellClass('NARROW'), 'shell-narrow page-body')
})

test('every width this module offers is a class theme.css actually defines', () => {
  // The contract now names these widths to module authors, so a rename in
  // theme.css has to fail here rather than silently in a module's page.
  const css = fs.readFileSync(path.join(HERE, '../src/styles/theme.css'), 'utf8')
  for (const w of SHELL_WIDTHS) {
    const cls = shellClass(w).split(' ')[0]
    assert.ok(css.includes(`.${cls} {`), `theme.css defines .${cls}`)
  }
  assert.ok(css.includes('.page-body {'), 'theme.css defines .page-body')
})
