/**
 * Inline data carried by a spec (docs/architecture/08 → editor augmentation).
 *
 * Portable core. When a view binds no named library dataset, its columns still
 * exist — inline, in `data.values` or a self-defined top-level `datasets` entry.
 * This pulls those rows out so the editor can profile them (core/profile) and offer
 * the same field hints a library-bound view gets — a "ghost dataset" derived from
 * the spec itself, with nothing stored.
 *
 * URL data has no rows to read statically, and `values` given as a CSV/TSV string
 * needs format-aware parsing — both out of scope here (they yield null).
 */

import { isJsonObject } from './spec-config';
import { classifyData, selfDefinedNames } from './spec-data';

/** An array of row objects, or null when the value is not tabular inline data. */
function asRows(value: unknown): Record<string, unknown>[] | null {
  if (Array.isArray(value) && value.length > 0 && value.every(isJsonObject)) {
    return value;
  }
  return null;
}

/**
 * The tabular rows a *specific* `data` binding provides for static profiling, or
 * null when it has none readable here: inline `data.values` (a JSON array of row
 * objects), or a self-defined `{ name }` resolved against the spec's top-level
 * `datasets`. A library `{ name }` reference (resolved from the dataset store), a
 * `url`, a generator, or a CSV/TSV string `values` payload yields null — those
 * carry no statically-readable JSON rows. Used by the view-scoped editor hints to
 * profile the data bound at the cursor (`dataBindingAtPath` → this).
 */
export function rowsForDataBinding(spec: unknown, data: unknown): Record<string, unknown>[] | null {
  const kind = classifyData(data);
  if (kind === 'inline') return asRows((data as { values: unknown }).values);
  if (kind === 'named') {
    const name = (data as { name: string }).name;
    if (selfDefinedNames(spec).has(name) && isJsonObject(spec) && isJsonObject(spec.datasets)) {
      return asRows((spec.datasets as Record<string, unknown>)[name]);
    }
  }
  return null;
}
