/*
 * 文件定位：Agent 模型适配层 / 真实上游调用层 / OpenAI 官方调用面。
 * 核心目的：承接 OpenAI 上游的 v1 organization users 真实调用面。
 * 能力要求1：需要把对应 endpoint 的请求参数、响应形态、错误形态和能力信号整理成可适配对象。
 * 能力要求2：鉴权/API 登录后续会接入，但这里要为“上游能力变得实际可用”预留位置。
 * 能力要求3：不把该 provider 的字段形状提升为 Praxis 统一语义，只作为 actualInvocationLayer 的现实入口。
 * 边界：只处理上游实际调用面，不在这里定义 agentCore 使用 AI 的统一方式。
 * 对接：需要被 runtime.modelAdapter 拉起，并和 provider/carrier、PromptPack lowering、能力抽象链路接通。
 * 实现提示：先补稳定类型契约、最小可测行为和清晰错误边界，再接入真实执行逻辑。
 */
export const OPENAI_V1_ORGANIZATION_USERS_ENDPOINT = "/v1/organization/users";
export const DEFAULT_OPENAI_V1_ORGANIZATION_USERS_BASE_URL = "https://api.openai.com";
export const openAIV1OrganizationUsersDescriptor = {
    provider: "openai",
    layer: "actualInvocationLayer",
    endpoint: OPENAI_V1_ORGANIZATION_USERS_ENDPOINT,
    methods: ["GET", "POST", "PATCH", "DELETE"],
    requestShape: "query-or-json",
    providerRawShapePromoted: false,
    unsafeSideEffects: false,
};
function hasText(value) {
    return typeof value === "string" && value.trim().length > 0;
}
function isRecord(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
function cleanScopes(scopes) {
    return [...new Set((scopes ?? []).map((scope) => scope.trim()).filter(Boolean))];
}
function cleanQuery(query) {
    const cleaned = {};
    for (const [rawKey, rawValue] of Object.entries(query ?? {})) {
        const key = rawKey.trim();
        if (key.length === 0 || rawValue === undefined) {
            continue;
        }
        cleaned[key] = String(rawValue);
    }
    return cleaned;
}
function cleanHeaders(headers) {
    const cleaned = {};
    for (const [rawKey, rawValue] of Object.entries(headers ?? {})) {
        const key = rawKey.trim().toLowerCase();
        const value = rawValue?.trim();
        if (key.length > 0 && value !== undefined && value.length > 0) {
            cleaned[key] = value;
        }
    }
    return cleaned;
}
function normalizeBaseUrl(baseUrl) {
    return hasText(baseUrl) ? baseUrl.trim().replace(/\/+$/, "") : DEFAULT_OPENAI_V1_ORGANIZATION_USERS_BASE_URL;
}
function cleanPathSuffix(pathSuffix) {
    return pathSuffix?.trim().replace(/^\/+/, "").replace(/\/+$/, "") ?? "";
}
function buildUrl(baseUrl, pathSuffix) {
    const suffix = cleanPathSuffix(pathSuffix);
    return suffix
        ? `${normalizeBaseUrl(baseUrl)}${OPENAI_V1_ORGANIZATION_USERS_ENDPOINT}/${suffix}`
        : `${normalizeBaseUrl(baseUrl)}${OPENAI_V1_ORGANIZATION_USERS_ENDPOINT}`;
}
function providerStatus(error) {
    if (!isRecord(error)) {
        return undefined;
    }
    const status = error.status ?? error.statusCode;
    return typeof status === "number" ? status : undefined;
}
function providerCode(error) {
    if (!isRecord(error)) {
        return "";
    }
    const code = error.code ?? error.name;
    return typeof code === "string" ? code.toLowerCase() : "";
}
function failure(code, message, boundary, retryable = false, request) {
    return {
        ok: false,
        error: {
            code,
            message,
            boundary,
            retryable,
            safeForRuntimeInspection: true,
            providerRawDetailExposed: false,
        },
        request,
        events: ["agentCore.modelAdapter.openai.v1.organization.users.rejected"],
    };
}
export function classifyOpenAIV1OrganizationUsersProviderError(error) {
    const status = providerStatus(error);
    const code = providerCode(error);
    if (status === 401 || status === 403) {
        return "PROVIDER_AUTH_FAILED";
    }
    if (status === 429) {
        return "PROVIDER_RATE_LIMITED";
    }
    if (status === 408 || code.includes("timeout") || code.includes("abort")) {
        return "PROVIDER_TIMEOUT";
    }
    if ((status !== undefined && status >= 500) || status === 404) {
        return "PROVIDER_UNAVAILABLE";
    }
    if (code.includes("format") || code.includes("schema") || code.includes("parse")) {
        return "RESPONSE_FORMAT_DRIFT";
    }
    return "PROVIDER_REJECTED";
}
function inferRawShape(operation, raw) {
    if (operation === "list" || (isRecord(raw) && Array.isArray(raw.data))) {
        return "organization-users-list";
    }
    if (isRecord(raw)) {
        return "organization-user-object";
    }
    return "mock";
}
export function createOpenAIV1OrganizationUsersInvocation(input = {}) {
    if (!hasText(input.operation)) {
        return failure("MISSING_OPERATION", "OpenAI v1 organization users invocation requires an explicit operation", "input");
    }
    const runtime = input.runtime;
    if (runtime === undefined || !hasText(runtime.runtimeId)) {
        return failure("MISSING_RUNTIME_ID", "OpenAI v1 organization users invocation requires runtime.runtimeId", "input");
    }
    if (input.query !== undefined && !isRecord(input.query)) {
        return failure("INVALID_QUERY", "OpenAI v1 organization users query must be a plain record", "input");
    }
    if (input.contract?.accepted === false) {
        return failure("CONTRACT_REJECTED", input.contract.reason ?? "OpenAI v1 organization users contract rejected the request", "contract");
    }
    if (input.governance?.accepted === false) {
        return failure("GOVERNANCE_REJECTED", input.governance.reason ?? "OpenAI v1 organization users governance rejected the request", "governance");
    }
    if (input.auth?.present === false) {
        return failure("AUTH_REJECTED", "OpenAI v1 organization users auth envelope is unavailable", "auth");
    }
    const requestedScopes = cleanScopes(input.requiredScopes);
    const allowedScopes = cleanScopes(input.allowedScopes);
    const deniedScopes = allowedScopes.length === 0 ? [] : requestedScopes.filter((scope) => !allowedScopes.includes(scope));
    if (deniedScopes.length > 0) {
        return failure("SCOPE_DENIED", `OpenAI v1 organization users requested scopes outside the allowed boundary: ${deniedScopes.join(", ")}`, "scope");
    }
    const operation = input.operation.trim();
    const request = {
        provider: "openai",
        apiVersion: "v1",
        endpoint: OPENAI_V1_ORGANIZATION_USERS_ENDPOINT,
        operation,
        method: input.method ?? "GET",
        url: buildUrl(input.baseUrl, input.pathSuffix),
        pathSuffix: cleanPathSuffix(input.pathSuffix),
        query: cleanQuery(input.query),
        headers: cleanHeaders(input.headers),
        body: input.body,
        runtime: {
            runtimeId: runtime.runtimeId.trim(),
            invocationId: runtime.invocationId?.trim() || "",
            traceId: runtime.traceId?.trim() || "",
            callerId: runtime.callerId?.trim() || "",
        },
        requestedScopes,
        grantedScopes: requestedScopes,
        dryRun: true,
        providerCallPlanned: false,
        unsafeSideEffects: false,
        providerFieldsOpaque: true,
    };
    if (input.dryRun === false) {
        return failure("REAL_PROVIDER_CALL_NOT_ALLOWED", "first-round OpenAI v1 organization users invocation only builds dry-run or mock envelopes", "governance", false, request);
    }
    if (input.providerError !== undefined) {
        const code = classifyOpenAIV1OrganizationUsersProviderError(input.providerError);
        return failure(code, `OpenAI v1 organization users provider failed with ${code}`, code === "RESPONSE_FORMAT_DRIFT" ? "response" : "provider", code === "PROVIDER_RATE_LIMITED" || code === "PROVIDER_TIMEOUT" || code === "PROVIDER_UNAVAILABLE", request);
    }
    if (input.expectResponseObject === true && input.mockResponse !== undefined && !isRecord(input.mockResponse)) {
        return failure("RESPONSE_FORMAT_DRIFT", "OpenAI v1 organization users mock response did not match the expected object envelope", "response", false, request);
    }
    return {
        ok: true,
        request,
        response: {
            provider: "openai",
            endpoint: OPENAI_V1_ORGANIZATION_USERS_ENDPOINT,
            mode: input.mockResponse === undefined ? "dry-run" : "mock",
            raw: input.mockResponse ?? null,
            providerFieldsOpaque: true,
        },
        capability: {
            provider: "openai",
            layer: "actualInvocationLayer",
            endpoint: OPENAI_V1_ORGANIZATION_USERS_ENDPOINT,
            operation,
            rawShape: input.mockResponse === undefined ? "dry-run" : inferRawShape(operation, input.mockResponse),
            providerRawShapePromoted: false,
        },
        events: ["agentCore.modelAdapter.openai.v1.organization.users.dryRun"],
    };
}
