import type { Turn } from "@best-agent/protocol";
import type { AgentProfile } from "../../agent/profile-registry.js";
import type { PreparedToolInvocation, ToolExecutionResultMetadata } from "../../tool/registry.js";
import type { ToolResumeContext } from "../checkpoint-codec.js";
import { runPostToolUseHooks } from "./tool-hook-runner.js";
import { persistToolOutput } from "./tool-result-persistence.js";
import type {
  PersistTerminalToolFailure,
  ToolExecutionRuntime,
  ToolShellDebugBase,
} from "./tool-execution-types.js";

export async function finalizeExecutedToolResult(input: {
  output: string;
  persistTerminalToolFailure: PersistTerminalToolFailure;
  prepared: PreparedToolInvocation;
  preparedToolResumeContext: ToolResumeContext;
  profile: AgentProfile;
  resultMetadata?: ToolExecutionResultMetadata;
  runtime: ToolExecutionRuntime;
  shellDebugBase?: ToolShellDebugBase;
  toolCallId: ToolResumeContext["toolCallId"];
  toolName: string;
  toolStartedAt: number;
  turn: Turn;
}): Promise<string> {
  const postHook = await runPostToolUseHooks({
    output: input.output,
    persistTerminalToolFailure: input.persistTerminalToolFailure,
    preparedToolResumeContext: input.preparedToolResumeContext,
    profile: input.profile,
    runtime: input.runtime,
    shellDebugBase: input.shellDebugBase,
    toolCallId: input.toolCallId,
    toolInput: input.prepared.normalizedInput,
    toolName: input.toolName,
    toolStartedAt: input.toolStartedAt,
    turn: input.turn,
  });
  if (postHook.failureOutput !== undefined) {
    return postHook.failureOutput;
  }

  await persistToolOutput({
    debugEventPrefix: "shell.result_persist",
    output: postHook.output,
    resultMetadata: input.resultMetadata,
    resumeContext: {
      ...input.preparedToolResumeContext,
      toolCallId: input.toolCallId,
    },
    runtime: input.runtime,
    shellDebugBase: input.shellDebugBase,
    toolCallId: input.toolCallId,
    toolInput: input.prepared.normalizedInput,
    toolName: input.toolName,
    turn: input.turn,
  });
  return postHook.output;
}
