import type { ItemId, ToolFailureKind, ToolInputValue, Turn, TurnId } from "@best-agent/protocol";
import type { AgentProfile } from "../../agent/profile-registry.js";
import type { ToolResumeContext } from "../checkpoint-codec.js";
import type { ExecuteToolInvocationOptions } from "../agent-runtime-tool-execution-types.js";
import type {
  PreparedToolExecutor,
  ToolApprovalService,
  ToolCapabilityService,
  ToolDelegationService,
  ToolEvidenceService,
  ToolFormattingService,
  ToolHookService,
  ToolReplayService,
  ToolRuntimeSampleService,
  ToolTraceService,
  WebSearchBudgetService,
} from "./tool-execution-service-types.js";
import type {
  ToolCallItemPersistence,
  ToolCheckpointPersistenceService,
  ToolFailurePersistenceService,
  ToolItemPersistenceService,
  ToolResultItemPersistence,
} from "./tool-execution-persistence-types.js";
import type {
  ToolInterruptionStore,
  ToolRunCheckpointStore,
  ToolTurnStateStore,
} from "./tool-execution-store-types.js";
import type { ThreadMetadata, ToolResultEnvelope, ToolResultOutcome } from "@best-agent/protocol";

export type ToolExecutionRuntime = {
  approvals: ToolApprovalService;
  capability: ToolCapabilityService;
  cwd: string;
  checkpointPersistence: ToolCheckpointPersistenceService;
  delegation: ToolDelegationService;
  evidence: ToolEvidenceService;
  failurePersistence: ToolFailurePersistenceService;
  formatting: ToolFormattingService;
  hooks: ToolHookService;
  interruptions: ToolInterruptionStore;
  items: ToolItemPersistenceService;
  preparedTools: PreparedToolExecutor;
  replay: ToolReplayService;
  runCheckpoints: ToolRunCheckpointStore;
  runtimeSample: ToolRuntimeSampleService;
  tracing: ToolTraceService;
  toolCalls: ToolCallItemPersistence;
  toolResults: ToolResultItemPersistence;
  turnState: ToolTurnStateStore;
  webSearchBudget: WebSearchBudgetService;
};

export type ToolExecutionRunnerInput = {
  activeSkillIds?: string[];
  approvalTurn?: Turn;
  input: ToolInputValue;
  options?: ExecuteToolInvocationOptions;
  previewCallId?: ItemId;
  profile: AgentProfile;
  reasoning?: string;
  toolName: string;
  turn: Turn;
};

export type ToolShellDebugBase = {
  profileName: string;
  threadId: import("@best-agent/protocol").ThreadId;
  turnId: TurnId;
};

export type PersistTerminalToolFailure = (
  toolCallId: ItemId,
  toolInput: ToolInputValue,
  resumeContext: ToolResumeContext | undefined,
  error: unknown,
  outputOverride?: string,
) => Promise<string | undefined>;

export type ToolResultFailureMetadata = {
  errorCode?: string;
  failureKind?: ToolFailureKind;
  outcome?: ToolResultOutcome;
  structuredContent?: ThreadMetadata;
  toolEnvelope?: Partial<ToolResultEnvelope>;
};
