/**
 * Every piece of jargon the site uses, with the one-sentence gloss a visitor
 * gets when they hover or tap it.
 *
 * One list, two audiences. The five `core` terms are the vocabulary of the
 * idea itself and are rendered as a set: in the header's "How it works" panel
 * and on the landing page. The extended terms are glossed inline, one at a
 * time, by `Term` wherever a page or the shell first uses the word.
 *
 * Glosses are sentences a board member can repeat. They say what the thing IS
 * before they say what it is for, and they never lean on another term from
 * this list to do it.
 */

export type GlossaryKey =
  | 'environment'
  | 'rollout'
  | 'reward'
  | 'harness'
  | 'held-out'
  | 'seed'
  | 'arm'
  | 'objective'
  | 'counterweight'
  | 'gate'
  | 'intervention'
  | 'verify'
  | 'taskset'
  | 'verifiers'
  | 'tokens'
  | 'latency';

export interface GlossaryEntry {
  key: GlossaryKey;
  /** As it is written in running text. Sentence case. */
  term: string;
  gloss: string;
  /** One of the five rendered as a set. */
  core: boolean;
}

export const GLOSSARY: readonly GlossaryEntry[] = [
  {
    key: 'environment',
    term: 'Environment',
    gloss:
      'The task, the legal moves and the grader, packaged so anyone can install and run it.',
    core: true,
  },
  {
    key: 'rollout',
    term: 'Rollout',
    gloss: 'One episode. The model acts, the environment answers, and every turn is recorded.',
    core: true,
  },
  {
    key: 'reward',
    term: 'Reward',
    gloss: 'The number the run is scored on. You write it, so you decide what "good" means.',
    core: true,
  },
  {
    key: 'harness',
    term: 'Harness',
    gloss: 'The runner that plays a taskset against a model and keeps the receipts.',
    core: true,
  },
  {
    key: 'held-out',
    term: 'Held-out grading',
    gloss:
      'Scored on problems the model has never seen, which is the only way the score means anything.',
    core: true,
  },
  {
    key: 'seed',
    term: 'Seed',
    gloss:
      'The number that fixes the board. The same seed reproduces the same hidden word, so two agents can be compared on the same puzzle.',
    core: false,
  },
  {
    key: 'arm',
    term: 'Arm',
    gloss:
      'One model under one setting, with its recorded runs. The ranking compares arms, not companies.',
    core: false,
  },
  {
    key: 'objective',
    term: 'Objective',
    gloss:
      'What the task is for: the term the agent is paid to maximise. Every other term in the reward exists to keep this one honest.',
    core: false,
  },
  {
    key: 'counterweight',
    term: 'Counterweight',
    gloss:
      'The term that takes points away. It pulls against the objective so the crude way of winning does not pay.',
    core: false,
  },
  {
    key: 'gate',
    term: 'Gate',
    gloss:
      'A term every good attempt also scores full marks on. It rules out cheating; it does not rank.',
    core: false,
  },
  {
    key: 'intervention',
    term: 'Intervention',
    gloss:
      'Something done to a run that was not training: a changed prompt, a hint. Always labelled, never presented as a training result.',
    core: false,
  },
  {
    key: 'verify',
    term: 'Verify',
    gloss:
      'Re-run the grader in your browser over the recorded moves and compare the answer to the number shipped in the file.',
    core: false,
  },
  {
    key: 'taskset',
    term: 'Taskset',
    gloss: 'The list of problems an environment draws from. On the word game, the hidden words.',
    core: false,
  },
  {
    key: 'verifiers',
    term: 'verifiers',
    gloss:
      'Prime Intellect’s open-source library for writing environments. Every environment on this site is built with it.',
    core: false,
  },
  {
    key: 'tokens',
    term: 'Tokens',
    gloss:
      'The units a model reads and writes. The counts here are what the recording measured, not a price.',
    core: false,
  },
  {
    key: 'latency',
    term: 'Latency',
    gloss:
      'Wall-clock time per model call, as recorded on that day against that endpoint. Not a benchmark.',
    core: false,
  },
];

/** The five rendered as a set, in the order they are taught. */
export const CORE_TERMS: readonly GlossaryEntry[] = GLOSSARY.filter((entry) => entry.core);

/** One entry by key. Throws at build time rather than rendering an empty tooltip. */
export function glossaryEntry(key: GlossaryKey): GlossaryEntry {
  const entry = GLOSSARY.find((e) => e.key === key);
  if (!entry) throw new Error(`No glossary entry "${key}".`);
  return entry;
}
