/**
 * lib/output.ts — Standardized stdout JSON envelope for dev CLIs.
 *
 * Every SmartStack Studio dev CLI returns a single JSON object on stdout.
 * This module provides helper functions to build that envelope consistently
 * so Claude can parse all CLIs with the same logic.
 *
 * Envelope shape:
 *   {
 *     success: boolean,
 *     command: string,
 *     data?: Record<string, unknown>,       // generic data bag
 *     filesCreated?: string[],              // for generate sub-pattern
 *     filesModified?: string[],             // for generate sub-pattern
 *     report?: Record<string, unknown>,     // for execute sub-pattern
 *     errors: string[],
 *     warnings: string[],
 *     nextSteps: string[],
 *   }
 */

export interface GenerateEnvelope {
  success: boolean;
  command: string;
  data?: Record<string, unknown>;
  filesCreated: string[];
  filesModified: string[];
  errors: string[];
  warnings: string[];
  nextSteps: string[];
}

export interface ExecuteEnvelope<R = Record<string, unknown>> {
  success: boolean;
  command: string;
  data?: Record<string, unknown>;
  report: R | null;
  errors: string[];
  warnings: string[];
  nextSteps: string[];
}

export type CliEnvelope<R = Record<string, unknown>> =
  | GenerateEnvelope
  | ExecuteEnvelope<R>;

export function generateEnvelope(
  command: string,
  overrides: Partial<GenerateEnvelope> = {},
): GenerateEnvelope {
  return {
    success: true,
    command,
    filesCreated: [],
    filesModified: [],
    errors: [],
    warnings: [],
    nextSteps: [],
    ...overrides,
  };
}

export function executeEnvelope<R = Record<string, unknown>>(
  command: string,
  overrides: Partial<ExecuteEnvelope<R>> = {},
): ExecuteEnvelope<R> {
  return {
    success: true,
    command,
    report: null,
    errors: [],
    warnings: [],
    nextSteps: [],
    ...overrides,
  };
}

/**
 * Print the envelope as pretty JSON on stdout.
 * Single source of truth for what Claude reads after invoking a CLI.
 *
 * Generic over the report shape so execute CLIs can print a strongly-typed
 * `ExecuteEnvelope<MyReport>` (an interface lacks the implicit index signature
 * of `Record<string, unknown>`). Pure widening — every existing caller still
 * compiles; runtime behaviour is unchanged (types are erased).
 */
export function printEnvelope<R = Record<string, unknown>>(envelope: CliEnvelope<R>): void {
  console.log(JSON.stringify(envelope, null, 2));
}

/** Convenience: build a failure envelope (generate variant). */
export function failGenerate(command: string, errors: string[]): GenerateEnvelope {
  return {
    success: false,
    command,
    filesCreated: [],
    filesModified: [],
    errors,
    warnings: [],
    nextSteps: [],
  };
}

/** Convenience: build a failure envelope (execute variant). */
export function failExecute<R = Record<string, unknown>>(
  command: string,
  errors: string[],
): ExecuteEnvelope<R> {
  return {
    success: false,
    command,
    report: null,
    errors,
    warnings: [],
    nextSteps: [],
  };
}
