/**
 * ADR-0027: Capability readiness probe. Validates the Alibaba Cloud docmind
 * credential by calling QueryDocParserStatus with a dummy id — a 400 (bad
 * request) means the credential is valid (the API accepted auth but rejected
 * the id); a 401/403 means the credential is bad.
 */
import { classifyNetworkFailure, type NetworkFailureCategory } from "../connections/networkFailure.js";

export interface CapabilityReadinessInput {
  readonly endpoint: string;
  readonly accessKeyId: string;
  readonly accessKeySecret: string;
}

export type CapabilityReadinessProbe = (input: CapabilityReadinessInput) => Promise<void>;

export class CapabilityReadinessError extends Error {
  constructor(
    readonly code: "capability_readiness_unsupported" | "capability_readiness_unreachable" | "capability_readiness_rejected",
    message: string,
    readonly category: NetworkFailureCategory | "configuration" | "http",
    readonly upstreamStatus?: number,
  ) {
    super(message);
    this.name = "CapabilityReadinessError";
  }
}

/**
 * Probe the Alibaba Cloud docmind credential. We call QueryDocParserStatus
 * with a dummy id. The API will return:
 *   - 400 (InvalidParameter) → credential valid, just a bad id → probe passes
 *   - 401/403 (InvalidAccessKey/Forbidden) → credential invalid → probe fails
 *   - network error → unreachable
 */
export const probeDocmindCredential: CapabilityReadinessProbe = async (input) => {
  const url = `https://${input.endpoint}/?Action=QueryDocParserStatus&Id=probe-test&Version=2022-07-11`;
  const authHeader = makeBasicAuth(input.accessKeyId, input.accessKeySecret);

  let response: Response;
  try {
    response = await fetch(url, {
      method: "GET",
      headers: { authorization: authHeader, accept: "application/json" },
      redirect: "manual",
      signal: AbortSignal.timeout(10_000),
    });
  } catch (error) {
    throw new CapabilityReadinessError(
      "capability_readiness_unreachable",
      "docmind credential readiness check could not reach the API",
      classifyNetworkFailure(error),
    );
  }
  await response.body?.cancel();
  if (response.status === 401 || response.status === 403) {
    throw new CapabilityReadinessError(
      "capability_readiness_rejected",
      `docmind credential rejected: status ${response.status}`,
      "http",
      response.status,
    );
  }
};

function makeBasicAuth(accessKeyId: string, accessKeySecret: string): string {
  const credentials = Buffer.from(`${accessKeyId}:${accessKeySecret}`).toString("base64");
  return `Basic ${credentials}`;
}
