function getDef(schema) {
    if (!schema || typeof schema !== "object")
        return undefined;
    return schema._def;
}
// Optional/Default/Nullable/Effects/Pipeline wrapping 을 모두 풀어 본질 타입을 반환.
export function unwrapZodType(schema) {
    let cur = schema;
    for (let i = 0; i < 8 && cur; i += 1) {
        const def = getDef(cur);
        if (!def)
            break;
        const t = def.typeName;
        if (t === "ZodOptional" || t === "ZodDefault" || t === "ZodNullable") {
            cur = def.innerType;
            continue;
        }
        if (t === "ZodEffects" && def.schema) {
            cur = def.schema;
            continue;
        }
        if (t === "ZodPipeline" && def.out) {
            cur = def.out;
            continue;
        }
        break;
    }
    return cur ?? schema;
}
// 필드가 optional 인지 (Optional 또는 Default 래퍼)
export function isOptional(schema) {
    const def = getDef(schema);
    if (!def)
        return false;
    return def.typeName === "ZodOptional" || def.typeName === "ZodDefault" || def.typeName === "ZodNullable";
}
export function getFieldKind(schema) {
    const unwrapped = unwrapZodType(schema);
    const def = getDef(unwrapped);
    if (!def)
        return "unknown";
    switch (def.typeName) {
        case "ZodString":
            return "string";
        case "ZodNumber":
            return "number";
        case "ZodBoolean":
            return "boolean";
        case "ZodArray":
            return "array";
        case "ZodObject":
        case "ZodRecord":
            return "object";
        case "ZodEnum":
        case "ZodLiteral":
            return "enum";
        case "ZodUnion":
            // union 의 첫 옵션을 따라감 (CLI 단순화)
            if (def.options && def.options.length > 0)
                return getFieldKind(def.options[0]);
            return "unknown";
        default:
            return "unknown";
    }
}
// description 추출 (Optional/Default 래퍼 통과)
export function getDescription(schema) {
    let cur = schema;
    for (let i = 0; i < 8 && cur; i += 1) {
        const def = getDef(cur);
        if (!def)
            break;
        if (def.description)
            return def.description;
        if (def.typeName === "ZodOptional" || def.typeName === "ZodDefault" || def.typeName === "ZodNullable") {
            cur = def.innerType;
            continue;
        }
        if (def.typeName === "ZodEffects" && def.schema) {
            cur = def.schema;
            continue;
        }
        break;
    }
    return undefined;
}
// ZodObject shape 추출 (Effects/Pipeline wrap 포함)
export function getObjectShape(schema) {
    const unwrapped = unwrapZodType(schema);
    const def = getDef(unwrapped);
    if (!def || def.typeName !== "ZodObject" || !def.shape)
        return null;
    const raw = typeof def.shape === "function" ? def.shape() : def.shape;
    return raw;
}
export function fieldToMeta(schema) {
    const optional = isOptional(schema);
    const unwrapped = unwrapZodType(schema);
    const def = getDef(unwrapped);
    const kind = getFieldKind(unwrapped);
    const description = getDescription(schema);
    // Default 값 추출
    let defaultValue;
    let cur = schema;
    for (let i = 0; i < 4 && cur; i += 1) {
        const d = getDef(cur);
        if (!d)
            break;
        if (d.typeName === "ZodDefault" && d.defaultValue) {
            try {
                defaultValue = d.defaultValue();
            }
            catch { }
            break;
        }
        if (d.typeName === "ZodOptional" || d.typeName === "ZodNullable") {
            cur = d.innerType;
            continue;
        }
        break;
    }
    const meta = { type: kind, optional, description };
    if (defaultValue !== undefined)
        meta.default = defaultValue;
    if (kind === "enum" && def?.values)
        meta.enumValues = def.values;
    if (kind === "array" && def?.type)
        meta.itemsType = getFieldKind(def.type);
    return meta;
}
export function toolInputToMeta(schema) {
    const shape = getObjectShape(schema);
    if (!shape)
        return { type: "object", properties: {}, required: [] };
    const properties = {};
    const required = [];
    for (const [key, fieldSchema] of Object.entries(shape)) {
        const meta = fieldToMeta(fieldSchema);
        properties[key] = meta;
        if (!meta.optional)
            required.push(key);
    }
    return { type: "object", properties, required };
}
//# sourceMappingURL=schema-introspection.js.map