// @lifecycle canonical - Utility helpers for identifying and validating chain prompts.
/**
 * Chain Utility Functions
 *
 * Provides helper functions for chain detection and validation.
 * MIGRATION: Simplified to support only markdown-embedded chains.
 * Modular chain functions are deprecated but maintained for compatibility.
 *
 *  of Chain System Migration (2025-01-30)
 */

import * as path from 'node:path';

import { ValidationError } from './errorHandling.js';
// REMOVED: All types from deleted chain-scaffolding.ts
// Modular chain system has been completely deprecated

const CHAIN_ID_PATTERN = /^[a-z0-9_-]+$/i;

function isPathInside(basePath: string, targetPath: string): boolean {
  const relative = path.relative(basePath, targetPath);
  return !relative.startsWith('..') && !path.isAbsolute(relative);
}

export function normalizeChainId(chainId: string): string {
  if (typeof chainId !== 'string') {
    throw new ValidationError('Chain ID must be a string');
  }

  const normalized = chainId.trim();

  if (normalized.length === 0) {
    throw new ValidationError('Chain ID is required');
  }

  if (!CHAIN_ID_PATTERN.test(normalized)) {
    throw new ValidationError(
      `Invalid chain ID "${normalized}": only letters, numbers, hyphen, and underscore are allowed`
    );
  }

  return normalized;
}

// ===== Utility-Specific Type Definitions =====
// Types used specifically by utility functions that don't exist in canonical chain types

/**
 * ChainStep interface for utility functions
 */
export interface ChainStep {
  promptId: string;
  stepName: string;
  executionType?: 'single' | 'chain';
  inputMapping?: Record<string, string>;
  outputMapping?: Record<string, string>;
  dependencies?: string[];
}

/** Minimal interface for chain detection — avoids importing full ConvertedPrompt from engine/. */
interface ChainablePrompt {
  chainSteps?: ChainStep[];
}

/**
 * Determines if a prompt is a chain based on the presence of chain steps
 * Replaces the redundant isChain boolean property
 */
export function isChainPrompt(prompt: ChainablePrompt): boolean {
  return (prompt.chainSteps?.length || 0) > 0;
}

/**
 * Get the number of steps in a chain prompt
 */
export function getChainStepCount(prompt: ChainablePrompt): number {
  return prompt.chainSteps?.length || 0;
}

/**
 * Validate that chain steps are properly formed
 */
export function validateChainSteps(steps: ChainStep[]): boolean {
  if (!steps || steps.length === 0) {
    return false;
  }

  return steps.every(
    (step) =>
      step.promptId &&
      step.stepName &&
      typeof step.promptId === 'string' &&
      typeof step.stepName === 'string'
  );
}

/**
 * Check if a prompt has valid chain steps
 * Combines presence check with validation
 */
export function hasValidChainSteps(prompt: ChainablePrompt): boolean {
  const steps = prompt.chainSteps;
  return steps ? validateChainSteps(steps) : false;
}

/**
 * Get chain information summary for a prompt
 */
export function getChainInfo(prompt: ChainablePrompt): {
  isChain: boolean;
  stepCount: number;
  isValid: boolean;
} {
  const steps = prompt.chainSteps;
  return {
    isChain: isChainPrompt(prompt),
    stepCount: getChainStepCount(prompt),
    isValid: steps ? validateChainSteps(steps) : false,
  };
}

// ===== REMOVED: Modular Chain Detection and Management =====
// ChainType enum and detectChainType() function removed
// All chain detection now uses isChainPrompt() and chainSteps property

/**
 * Check if a prompt is a chain with valid steps (replaces legacy isMonolithicChain)
 */
export function isValidChain(prompt: ChainablePrompt): boolean {
  return isChainPrompt(prompt) && hasValidChainSteps(prompt);
}

// Modular chain system fully removed
// All chain management now uses markdown-embedded chainSteps property
