"use strict";
/* eslint-disable @typescript-eslint/no-unused-vars */
Object.defineProperty(exports, "__esModule", { value: true });
exports.adjustObjectType = adjustObjectType;
exports.removeAdditionalProperties = removeAdditionalProperties;
exports.schemaToGeminiParameters = schemaToGeminiParameters;
exports.jsonSchemaToGeminiParameters = jsonSchemaToGeminiParameters;
const types_1 = require("@langchain/core/utils/types");
const json_schema_1 = require("@langchain/core/utils/json_schema");
/* eslint-disable no-param-reassign */
function adjustObjectType(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) {
    if (!Array.isArray(obj.type)) {
        return obj;
    }
    const len = obj.type.length;
    const nullIndex = obj.type.indexOf("null");
    if (len === 2 && nullIndex >= 0) {
        // There are only two values set for the type, and one of them is "null".
        // Set the type to the other one and set nullable to true.
        const typeIndex = nullIndex === 0 ? 1 : 0;
        obj.type = obj.type[typeIndex];
        obj.nullable = true;
    }
    else if (len === 1 && nullIndex === 0) {
        // This is nullable only without a type, which doesn't
        // make sense for Gemini
        throw new Error("zod_to_gemini_parameters: Gemini cannot handle null type");
    }
    else if (len === 1) {
        // Although an array, it has only one value.
        // So set it to the string to match what Gemini expects.
        obj.type = obj?.type[0];
    }
    else {
        // Anything else could be a union type, so reject it.
        throw new Error("zod_to_gemini_parameters: Gemini cannot handle union types");
    }
    return obj;
}
/* eslint-enable no-param-reassign */
function removeAdditionalProperties(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj) {
    if (typeof obj === "object" && obj !== null) {
        const newObj = { ...obj };
        if ("additionalProperties" in newObj) {
            delete newObj.additionalProperties;
        }
        adjustObjectType(newObj);
        for (const key in newObj) {
            if (key in newObj) {
                if (Array.isArray(newObj[key])) {
                    newObj[key] = newObj[key].map(removeAdditionalProperties);
                }
                else if (typeof newObj[key] === "object" && newObj[key] !== null) {
                    newObj[key] = removeAdditionalProperties(newObj[key]);
                }
            }
        }
        return newObj;
    }
    return obj;
}
function schemaToGeminiParameters(schema) {
    // Gemini doesn't accept either the $schema or additionalProperties
    // attributes, so we need to explicitly remove them.
    // Zod sometimes also makes an array of type (because of .nullish()),
    // which needs cleaning up.
    const jsonSchema = removeAdditionalProperties((0, types_1.isInteropZodSchema)(schema) ? (0, json_schema_1.toJsonSchema)(schema) : schema);
    const { $schema, ...rest } = jsonSchema;
    return rest;
}
function jsonSchemaToGeminiParameters(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
schema) {
    // Gemini doesn't accept either the $schema or additionalProperties
    // attributes, so we need to explicitly remove them.
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const jsonSchema = removeAdditionalProperties(schema);
    const { $schema, ...rest } = jsonSchema;
    return rest;
}
