import {
  GenerateCodeContext,
  GenerateCodeResult,
  NodeManifest,
  NodeRegistry,
  PluginSettings,
} from "./v2-alpha-types";

/**
 * Base class for V2-Alpha plugins
 *
 * All plugins must extend this class and implement the required methods.
 * This follows the definition/execution pattern for clean code generation.
 */
export abstract class BasePlugin {
  /**
   * The plugin manifest defining inputs, outputs, and metadata
   */
  abstract manifest: NodeManifest;

  /**
   * Generate class definitions, functions, and other declarations
   * that need to be defined before execution.
   *
   * @param ctx - The code generation context
   * @param registry - The node registry for accessing other nodes
   * @returns Code, imports, and requirements for definitions
   */
  async generateDefinition(
    ctx: GenerateCodeContext,
    registry: NodeRegistry
  ): Promise<GenerateCodeResult> {
    // Default implementation returns empty
    return { code: "" };
  }

  /**
   * Generate the execution code that uses the definitions.
   * This is where the actual runtime logic goes.
   *
   * @param ctx - The code generation context
   * @param registry - The node registry for accessing other nodes
   * @returns Code, imports, and requirements for execution
   */
  abstract generateExecution(
    ctx: GenerateCodeContext,
    registry: NodeRegistry
  ): Promise<GenerateCodeResult>;

  /**
   * Helper to get input variable names from connected nodes
   */
  protected getInputVar(ctx: GenerateCodeContext, inputId: string): string {
    return ctx.getGlobalInputVarName(inputId) || inputId;
  }

  /**
   * Helper to generate a unique variable name for this node
   */
  protected getNodeVar(ctx: GenerateCodeContext, suffix: string = ""): string {
    const base =
      this.manifest.id.split("/").pop()?.replace(/-/g, "_") || "node";
    return suffix ? `${base}_${ctx.nodeId}_${suffix}` : `${base}_${ctx.nodeId}`;
  }
}
