/**
 * Toolkit - Type Assertions
 * 
 * Runtime assertion utilities for type safety.
 */

export class AssertionError extends Error {
  constructor(message: string) {
    super(message);
    this.name = "AssertionError";
  }
}

/**
 * Assert that a value is truthy
 */
export function assert(condition: unknown, message = "Assertion failed"): asserts condition {
  if (!condition) {
    throw new AssertionError(message);
  }
}

/**
 * Assert that a value is defined (not null or undefined)
 */
export function assertDefined<T>(
  value: T | null | undefined,
  message = "Value must be defined"
): asserts value is T {
  if (value === null || value === undefined) {
    throw new AssertionError(message);
  }
}

/**
 * Assert that a value is a string
 */
export function assertString(
  value: unknown,
  message = "Value must be a string"
): asserts value is string {
  if (typeof value !== "string") {
    throw new AssertionError(message);
  }
}

/**
 * Assert that a value is a number
 */
export function assertNumber(
  value: unknown,
  message = "Value must be a number"
): asserts value is number {
  if (typeof value !== "number" || isNaN(value)) {
    throw new AssertionError(message);
  }
}

/**
 * Assert that a value is never reached (exhaustiveness check)
 */
export function assertNever(value: never, message = "Unexpected value"): never {
  throw new AssertionError(`${message}: ${JSON.stringify(value)}`);
}

