// Ported from js-yaml v3.13.1:
// https://github.com/nodeca/js-yaml/commit/665aadda42349dcae869f12040d9b10ef18d12da
// Copyright 2011-2015 by Vitaly Puzrin. All rights reserved. MIT license.
// Copyright 2018-2025 the Deno authors. MIT license.
import { isNegativeZero } from "../_utils.js";
function isCharCodeInRange(c, lower, upper) {
    return lower <= c && c <= upper;
}
function isHexCode(c) {
    return (isCharCodeInRange(c, 0x30, 0x39) || // 0-9
        isCharCodeInRange(c, 0x41, 0x46) || // A-F
        isCharCodeInRange(c, 0x61, 0x66) // a-f
    );
}
function isOctCode(c) {
    return isCharCodeInRange(c, 0x30, 0x37); // 0-7
}
function isDecCode(c) {
    return isCharCodeInRange(c, 0x30, 0x39); // 0-9
}
function resolveYamlInteger(data) {
    const max = data.length;
    let index = 0;
    let hasDigits = false;
    if (!max)
        return false;
    let ch = data[index];
    // sign
    if (ch === "-" || ch === "+") {
        ch = data[++index];
    }
    if (ch === "0") {
        // 0
        if (index + 1 === max)
            return true;
        ch = data[++index];
        // base 2, base 8, base 16
        if (ch === "b") {
            // base 2
            index++;
            for (; index < max; index++) {
                ch = data[index];
                if (ch === "_")
                    continue;
                if (ch !== "0" && ch !== "1")
                    return false;
                hasDigits = true;
            }
            return hasDigits && ch !== "_";
        }
        if (ch === "x") {
            // base 16
            index++;
            for (; index < max; index++) {
                ch = data[index];
                if (ch === "_")
                    continue;
                if (!isHexCode(data.charCodeAt(index)))
                    return false;
                hasDigits = true;
            }
            return hasDigits && ch !== "_";
        }
        // base 8
        for (; index < max; index++) {
            ch = data[index];
            if (ch === "_")
                continue;
            if (!isOctCode(data.charCodeAt(index)))
                return false;
            hasDigits = true;
        }
        return hasDigits && ch !== "_";
    }
    // base 10 (except 0) or base 60
    // value should not start with `_`;
    if (ch === "_")
        return false;
    for (; index < max; index++) {
        ch = data[index];
        if (ch === "_")
            continue;
        if (!isDecCode(data.charCodeAt(index))) {
            return false;
        }
        hasDigits = true;
    }
    // Should have digits and should not end with `_`
    if (!hasDigits || ch === "_")
        return false;
    // base60 almost not used, no needs to optimize
    return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
}
function constructYamlInteger(data) {
    let value = data;
    if (value.includes("_")) {
        value = value.replace(/_/g, "");
    }
    let sign = 1;
    let ch = value[0];
    if (ch === "-" || ch === "+") {
        if (ch === "-")
            sign = -1;
        value = value.slice(1);
        ch = value[0];
    }
    if (value === "0")
        return 0;
    if (ch === "0") {
        if (value[1] === "b")
            return sign * parseInt(value.slice(2), 2);
        if (value[1] === "x")
            return sign * parseInt(value, 16);
        return sign * parseInt(value, 8);
    }
    return sign * parseInt(value, 10);
}
function isInteger(object) {
    if (object instanceof Number)
        object = object.valueOf();
    return typeof object === "number" && object % 1 === 0 &&
        !isNegativeZero(object);
}
export const int = {
    tag: "tag:yaml.org,2002:int",
    construct: constructYamlInteger,
    defaultStyle: "decimal",
    kind: "scalar",
    predicate: isInteger,
    represent: {
        // deno-lint-ignore ban-types
        binary(object) {
            const value = object instanceof Number ? object.valueOf() : object;
            return value >= 0
                ? `0b${value.toString(2)}`
                : `-0b${value.toString(2).slice(1)}`;
        },
        // deno-lint-ignore ban-types
        octal(object) {
            const value = object instanceof Number ? object.valueOf() : object;
            return value >= 0
                ? `0${value.toString(8)}`
                : `-0${value.toString(8).slice(1)}`;
        },
        // deno-lint-ignore ban-types
        decimal(object) {
            const value = object instanceof Number ? object.valueOf() : object;
            return value.toString(10);
        },
        // deno-lint-ignore ban-types
        hexadecimal(object) {
            const value = object instanceof Number ? object.valueOf() : object;
            return value >= 0
                ? `0x${value.toString(16).toUpperCase()}`
                : `-0x${value.toString(16).toUpperCase().slice(1)}`;
        },
    },
    resolve: resolveYamlInteger,
};
