"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateActionExecutionInterface = generateActionExecutionInterface;
const generator_1 = require("@postxl/generator");
function generateActionExecutionInterface({ actions, types }) {
    const { execution } = actions;
    const { mutations, transformation, errorOperation } = execution;
    const id = execution.interface.actionOperationId.name;
    const imports = generator_1.ImportGenerator
        //
        .from(execution.interface.location)
        .addType(actions.summary.action)
        .addType(types.modelNames)
        .addType(types.user);
    return /* ts */ `
${imports.generate()}

export type ${id} = string & { readonly ___type: 'Mutation' }

/**
 * Flags the given string as a ${id}.
 */
export const ${execution.interface.toBrandedActionOperationId.name} = (id: string): ${id} => id as ${id}

/**
 * The interface of the action executor.
 */
export interface ${execution.interface.name} {
  name: string
  user: User
  init({ action, user }: { action: Action; user: User }): Promise<void>

  /**
   * Marks the ActionExecution as finished successfully.
   *
   * This method needs to accept anything that the actual dispatcher functions can return.
   * This is often "void" - but can also be any other type.
   */
  // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
  success(result?: object | null | undefined | void): Promise<void>

  /**
   * Marks the ActionExecution as finished with an error.
   */
  error(error: unknown): Promise<void>

  ${mutations.create.start}({
    model,
    createObject,
  }: {
    model: ModelName
    createObject: object
  }): Promise<${id}> 

  ${mutations.createMany.start}({
    model,
    createObjects,
  }: {
    model: ModelName
    createObjects: object[]
  }): Promise<${id}> 

  ${mutations.update.start}({
    model,
    entityId,
    sourceObject,
    updateObject,
  }: {
    model: ModelName
    entityId: string
    sourceObject: object
    updateObject: object
  }): Promise<${id}>

  ${mutations.updateMany.start}({
    model,
    sourceObjects,
    updateObjects,
  }: {
    model: ModelName
    sourceObjects: object[]
    updateObjects: object[]
  }): Promise<${id}>

  ${mutations.delete.start}({
    model,
    entityId,
    sourceObject,
  }: {
    model: ModelName
    entityId: string
    sourceObject: object
  }): Promise<${id}>

  ${mutations.deleteMany.start}({
    model,
    entityIds,
    sourceObjects,
  }: {
    model: ModelName
    entityIds: string[]
    sourceObjects: object[]
  }): Promise<${id}>

  ${mutations.clone.start}({
    model,
    entityId,
    sourceObject,
  }: {
    model: ModelName
    entityId: string
    sourceObject: object
  }): Promise<${id}>

  ${mutations.create.finish}({
    actionOperationId,
    entityId,
    createdObject,
  }: {
    actionOperationId: ${id}
    entityId: string
    createdObject: object
  }): Promise<void>

  ${mutations.createMany.finish}({
    actionOperationId,
    entityIds,
    createdObjects,
  }: {
    actionOperationId: ${id}
    entityIds: string[]
    createdObjects: object[]
  }): Promise<void>
  
  ${mutations.update.finish}({ actionOperationId, updatedObject }: { actionOperationId: ${id}; updatedObject: object }): Promise<void> 

  ${mutations.updateMany.finish}({ actionOperationId, updatedObjects }: { actionOperationId: ${id}; updatedObjects: object[] }): Promise<void>

  ${mutations.delete.finish}({ actionOperationId }: { actionOperationId: ${id} }): Promise<void>

  ${mutations.deleteMany.finish}({ actionOperationId }: { actionOperationId: ${id} }): Promise<void>

  ${mutations.clone.finish}({ actionOperationId, clonedObject }: { actionOperationId: ${id}; clonedObject: object }): Promise<void>

  ${transformation.executeMultiple}<TInitial, T1>(
    steps: readonly [[operation: string, predicate: (input: TInitial) => T1 | Promise<T1>]],
    initialValue: TInitial,
  ): Promise<T1>
  ${transformation.executeMultiple}<TInitial, T1, T2>(
    steps: readonly [
      [operation: string, predicate: (input: TInitial) => T1 | Promise<T1>],
      [operation: string, predicate: (input: T1) => T2 | Promise<T2>],
    ],
    initialValue: TInitial,
  ): Promise<T2>
  ${transformation.executeMultiple}<TInitial, T1, T2, T3>(
    steps: readonly [
      [operation: string, predicate: (input: TInitial) => T1 | Promise<T1>],
      [operation: string, predicate: (input: T1) => T2 | Promise<T2>],
      [operation: string, predicate: (input: T2) => T3 | Promise<T3>],
    ],
    initialValue: TInitial,
  ): Promise<T3>
  ${transformation.executeMultiple}<TInitial, T1, T2, T3, T4>(
    steps: readonly [
      [operation: string, predicate: (input: TInitial) => T1 | Promise<T1>],
      [operation: string, predicate: (input: T1) => T2 | Promise<T2>],
      [operation: string, predicate: (input: T2) => T3 | Promise<T3>],
      [operation: string, predicate: (input: T3) => T4 | Promise<T4>],
    ],
    initialValue: TInitial,
  ): Promise<T4>
  ${transformation.executeMultiple}<TInitial, T1, T2, T3, T4, T5>(
    steps: readonly [
      [operation: string, predicate: (input: TInitial) => T1 | Promise<T1>],
      [operation: string, predicate: (input: T1) => T2 | Promise<T2>],
      [operation: string, predicate: (input: T2) => T3 | Promise<T3>],
      [operation: string, predicate: (input: T3) => T4 | Promise<T4>],
      [operation: string, predicate: (input: T4) => T5 | Promise<T5>],
    ],
    initialValue: TInitial,
  ): Promise<T5>
  ${transformation.executeMultiple}<TInitial, T1, T2, T3, T4, T5, T6>(
    steps: readonly [
      [operation: string, predicate: (input: TInitial) => T1 | Promise<T1>],
      [operation: string, predicate: (input: T1) => T2 | Promise<T2>],
      [operation: string, predicate: (input: T2) => T3 | Promise<T3>],
      [operation: string, predicate: (input: T3) => T4 | Promise<T4>],
      [operation: string, predicate: (input: T4) => T5 | Promise<T5>],
      [operation: string, predicate: (input: T5) => T6 | Promise<T6>],
    ],
    initialValue: TInitial,
  ): Promise<T6>
  ${transformation.executeMultiple}<TInitial, T1, T2, T3, T4, T5, T6, T7>(
    steps: readonly [
      [operation: string, predicate: (input: TInitial) => T1 | Promise<T1>],
      [operation: string, predicate: (input: T1) => T2 | Promise<T2>],
      [operation: string, predicate: (input: T2) => T3 | Promise<T3>],
      [operation: string, predicate: (input: T3) => T4 | Promise<T4>],
      [operation: string, predicate: (input: T4) => T5 | Promise<T5>],
      [operation: string, predicate: (input: T5) => T6 | Promise<T6>],
      [operation: string, predicate: (input: T6) => T7 | Promise<T7>],
    ],
    initialValue: TInitial,
  ): Promise<T7>

  ${transformation.executeSingle}<Payload extends object, Result extends object>({
    operation,
    payload,
    predicate,
  }: {
    operation: string
    payload: Payload
    predicate: (input: Payload) => Result | Promise<Result>
  }): Promise<Result>

  ${transformation.start}({
    operation,
    payload,
  }: {
    operation: string
    payload: object
  }): Promise<${id}>

  ${transformation.finish}({
    actionOperationId,
    result,
  }: {
    actionOperationId: ${id}
    result: object
  }): Promise<void>
  
  ${errorOperation}({ actionOperationId, error }: { actionOperationId: ${id}; error: unknown }): Promise<void> 
}
`;
}
//# sourceMappingURL=execution-interface.generator.js.map