"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.intRange = void 0;
const codegen_1 = require("../../compile/codegen");
const timestamp_1 = require("../../runtime/timestamp");
const util_1 = require("../../compile/util");
const metadata_1 = require("./metadata");
const error_1 = require("./error");
exports.intRange = {
    int8: [-128, 127, 3],
    uint8: [0, 255, 3],
    int16: [-32768, 32767, 5],
    uint16: [0, 65535, 5],
    int32: [-2147483648, 2147483647, 10],
    uint32: [0, 4294967295, 10],
};
const error = {
    message: (cxt) => error_1.typeErrorMessage(cxt, cxt.schema),
    params: (cxt) => error_1.typeErrorParams(cxt, cxt.schema),
};
function timestampCode(cxt) {
    const { gen, data, it } = cxt;
    const { timestamp, allowDate } = it.opts;
    if (timestamp === "date")
        return codegen_1._ `${data} instanceof Date `;
    const vts = util_1.useFunc(gen, timestamp_1.default);
    const allowDateArg = allowDate ? codegen_1._ `, true` : codegen_1.nil;
    const validString = codegen_1._ `typeof ${data} == "string" && ${vts}(${data}${allowDateArg})`;
    return timestamp === "string" ? validString : codegen_1.or(codegen_1._ `${data} instanceof Date`, validString);
}
const def = {
    keyword: "type",
    schemaType: "string",
    error,
    code(cxt) {
        metadata_1.checkMetadata(cxt);
        const { data, schema, parentSchema, it } = cxt;
        let cond;
        switch (schema) {
            case "boolean":
            case "string":
                cond = codegen_1._ `typeof ${data} == ${schema}`;
                break;
            case "timestamp": {
                cond = timestampCode(cxt);
                break;
            }
            case "float32":
            case "float64":
                cond = codegen_1._ `typeof ${data} == "number"`;
                break;
            default: {
                const sch = schema;
                cond = codegen_1._ `typeof ${data} == "number" && isFinite(${data}) && !(${data} % 1)`;
                if (!it.opts.int32range && (sch === "int32" || sch === "uint32")) {
                    if (sch === "uint32")
                        cond = codegen_1._ `${cond} && ${data} >= 0`;
                }
                else {
                    const [min, max] = exports.intRange[sch];
                    cond = codegen_1._ `${cond} && ${data} >= ${min} && ${data} <= ${max}`;
                }
            }
        }
        cxt.pass(parentSchema.nullable ? codegen_1.or(codegen_1._ `${data} === null`, cond) : cond);
    },
};
exports.default = def;
//# sourceMappingURL=type.js.map