"use strict";
/**
 * Convert between Nexus runtime objects and plain JS values.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.fromJs = fromJs;
exports.toJs = toJs;
exports.asString = asString;
exports.asInt = asInt;
exports.asBool = asBool;
exports.hashGetString = hashGetString;
exports.expectArgs = expectArgs;
exports.expectMinArgs = expectMinArgs;
const values_1 = require("../language/values");
function fromJs(value) {
    if (value === null || value === undefined) {
        return values_1.NULL_OBJ;
    }
    if (value instanceof Error) {
        return new values_1.ErrorObj(value.message);
    }
    if (typeof value === "boolean") {
        return value ? values_1.TRUE_OBJ : values_1.FALSE_OBJ;
    }
    if (typeof value === "number") {
        return new values_1.IntegerObj(Math.trunc(value));
    }
    if (typeof value === "string") {
        return new values_1.StringObj(value);
    }
    if (Array.isArray(value)) {
        return new values_1.ArrayObj(value.map((el) => fromJs(el)));
    }
    if (typeof value === "object") {
        const h = new values_1.HashObj();
        for (const [k, v] of Object.entries(value)) {
            h.setString(k, fromJs(v));
        }
        return h;
    }
    return new values_1.StringObj(String(value));
}
function toJs(obj) {
    if (obj.type === "NULL") {
        return null;
    }
    if (obj instanceof values_1.BooleanObj) {
        return obj.value;
    }
    if (obj instanceof values_1.IntegerObj) {
        return obj.value;
    }
    if (obj instanceof values_1.StringObj) {
        return obj.value;
    }
    if (obj instanceof values_1.ArrayObj) {
        return obj.elements.map((el) => toJs(el));
    }
    if (obj instanceof values_1.HashObj) {
        const out = {};
        for (const { key, value } of obj.pairs.values()) {
            const k = key instanceof values_1.StringObj
                ? key.value
                : key instanceof values_1.IntegerObj
                    ? String(key.value)
                    : key.inspect();
            out[k] = toJs(value);
        }
        return out;
    }
    if (obj instanceof values_1.ErrorObj) {
        return { error: obj.message };
    }
    return obj.inspect();
}
function asString(obj) {
    if (!obj) {
        return null;
    }
    if (obj instanceof values_1.StringObj) {
        return obj.value;
    }
    return null;
}
function asInt(obj) {
    if (!obj) {
        return null;
    }
    if (obj instanceof values_1.IntegerObj) {
        return obj.value;
    }
    if (obj instanceof values_1.StringObj) {
        const n = Number.parseInt(obj.value, 10);
        return Number.isNaN(n) ? null : n;
    }
    return null;
}
function asBool(obj) {
    if (!obj || obj.type === "NULL") {
        return false;
    }
    if (obj instanceof values_1.BooleanObj) {
        return obj.value;
    }
    if (obj instanceof values_1.IntegerObj) {
        return obj.value !== 0;
    }
    if (obj instanceof values_1.StringObj) {
        const s = obj.value.toLowerCase();
        return s === "true" || s === "1" || s === "yes";
    }
    return true;
}
function hashGetString(hash, key) {
    const v = hash.getString(key);
    if (v instanceof values_1.StringObj) {
        return v.value;
    }
    if (v.type === "NULL") {
        return "";
    }
    return v.inspect();
}
function expectArgs(name, n, args) {
    if (args.length !== n) {
        return new values_1.ErrorObj(`${name}: wrong number of arguments. got=${args.length}, want=${n}`);
    }
    return null;
}
function expectMinArgs(name, n, args) {
    if (args.length < n) {
        return new values_1.ErrorObj(`${name}: wrong number of arguments. got=${args.length}, want>=${n}`);
    }
    return null;
}
//# sourceMappingURL=convert.js.map