"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flattenUiPdoMapping = exports.uiConfigWithDefaultPdoMapping = exports.parsePdoSubItemValue = exports.splitDeviceParameterId = exports.deviceParameterIdRegExp = exports.makeDeviceParameterId = void 0;
const parameter_1 = require("./parameter");
/**
 * Constructs a device parameter ID string from a device serial number and parameter identifiers.
 *
 * The resulting ID has the format:
 * ```
 * <parameterId>.<serialNumber>
 * ```
 * where `<parameterId>` is generated by `makeParameterId` and `<serialNumber>` is the device's serial number.
 *
 * @param serialNumber - The serial number of the device.
 * @param a - Optional parameter identifier. Can be:
 *   - a number representing the index,
 *   - an object with optional `index` and `subindex` properties,
 *   - a tuple `[index, subindex]` where each element may be `number`, `null`, or `undefined`.
 * @param b - Optional subindex if `a` is provided as a number.
 *
 * @returns The constructed device parameter ID string in the format `<parameterId>.<serialNumber>`.
 *
 * @example
 * ```ts
 * const id1 = makeDeviceParameterId("Device123", 0x6040, 0x00);
 * // id1 = "0x6040:00.Device123"
 *
 * const id2 = makeDeviceParameterId("Device123", { index: 0x6040, subindex: 0x01 });
 * // id2 = "0x6040:01.Device123"
 *
 * const id3 = makeDeviceParameterId("Device123", [0x6040, 0x02]);
 * // id3 = "0x6040:02.Device123"
 * ```
 */
function makeDeviceParameterId(serialNumber, a, b) {
    const parameterId = (0, parameter_1.makeParameterId)(a, b);
    return `${parameterId}.${serialNumber}`;
}
exports.makeDeviceParameterId = makeDeviceParameterId;
/**
 * Example of device parameter id is "0x2110:1A.8502-03-0001353-2115" where:
 * - 0x2110 is object index in hexadecimal format
 * - 1A is subindex in hexadecimal format
 * - 8502-03-0001353-2115 is device serial number from hardware description file
 */
exports.deviceParameterIdRegExp = /^0x([0-9a-fA-F]{4,}):([0-9a-fA-F]{2})\.([\d-]+)$/;
/**
 * Splits a device parameter ID string into its components: index, subindex, and device serial number.
 *
 * The expected format of the ID must match `deviceParameterIdRegExp`.
 * If the ID does not match the expected format, an error is thrown.
 *
 * @param id - The device parameter ID string to split.
 * @returns A tuple `[index, subindex, deviceSerial]` where:
 *   - `index` is the 16-bit parameter index (parsed from hexadecimal),
 *   - `subindex` is the 8-bit parameter subindex (parsed from hexadecimal),
 *   - `deviceSerial` is the device serial number as a string.
 *
 * @throws {Error} If the provided ID does not match the expected regular expression.
 *
 * @example
 * ```ts
 * const id = "0x6040:00.123-ABC";
 * const [deviceSerial, index, subindex] = splitDeviceParameterId(id);
 * // deviceSerial = "123-ABC"
 * // index = 0x6040
 * // subindex = 0x00
 * ```
 */
function splitDeviceParameterId(id) {
    const match = id.match(exports.deviceParameterIdRegExp);
    if (!match) {
        throw new Error(`Device parameter id "${id}" doesn't match the regular expression: ${exports.deviceParameterIdRegExp}`);
    }
    return [
        match[3],
        parseInt(match[1], 16),
        parseInt(match[2], 16), // subindex
    ];
}
exports.splitDeviceParameterId = splitDeviceParameterId;
/**
 * Parses a 32-bit encoded PDO subitem value into its components.
 *
 * The 32-bit value is structured as follows:
 * ```
 * Bits  | Field
 * ------|--------
 *  0–7  | Bit length (bitlen)
 *  8–15 | Subindex
 * 16–31 | Index
 * ```
 *
 * @param value - The 32-bit encoded PDO subitem value.
 * @returns A tuple `[index, subindex, bitlen]` where:
 * - `index` — The 16-bit parameter index.
 * - `subindex` — The 8-bit parameter subindex.
 * - `bitlen` — The bit length of the mapped item.
 */
function parsePdoSubItemValue(value) {
    const b0 = value & 0xff;
    const b1 = (value >> 8) & 0xff;
    const b2 = (value >> 16) & 0xff;
    const b3 = (value >> 24) & 0xff;
    const index = (b3 << 8) | b2;
    const subindex = b1;
    const bitlen = b0;
    return [index, subindex, bitlen];
}
exports.parsePdoSubItemValue = parsePdoSubItemValue;
/**
 * Default UI configuration containing the PDO mapping.
 *
 * This configuration is used as a fallback when a device-specific UI configuration
 * is not available. It defines both RX (receive) and TX (transmit) PDOs with
 * their corresponding object dictionary entries.
 *
 * ⚠️ Important: Keep this in sync with the default PDO mapping in Motion Master
 * to ensure consistent behavior across devices.
 */
exports.uiConfigWithDefaultPdoMapping = {
    pdoMapping: {
        rx: {
            '0x1600': ['0x60400010', '0x60600008', '0x60710010', '0x607a0020', '0x60ff0020', '0x60b20010', '0x27010020'],
            '0x1601': ['0x60fe0120', '0x60fe0220'],
            '0x1602': ['0x27030020', '0x60b10020', '0x20120120'],
        },
        tx: {
            '0x1a00': [
                '0x60410010',
                '0x60610008',
                '0x60640020',
                '0x606c0020',
                '0x60770010',
                '0x60f40020',
                '0x21110220',
                '0x21130220',
            ],
            '0x1a01': ['0x24010010', '0x24020010', '0x24030010', '0x24040010', '0x27020020'],
            '0x1a02': ['0x60fd0020'],
            '0x1a03': ['0x27040020', '0x20f00020', '0x60fc0020', '0x606b0020', '0x60740010', '0x60790020'],
        },
    },
};
/**
 * Flattens a PDO mapping into an array of [deviceRef, index, subindex] entries.
 *
 * This function iterates over both RX and TX PDOs in the provided `pdoMapping` and
 * extracts the index and subindex from each 32-bit PDO entry using `parsePdoSubItemValue`.
 *
 * @param deviceRef - The reference to the device associated with this PDO mapping.
 * @param pdoMapping - The UI PDO mapping object containing RX and TX PDO entries.
 * @returns An array where each item is a tuple `[deviceRef, index, subindex]`.
 *
 * @example
 * ```ts
 * const deviceRef = 1;
 * const flatArray = flattenUiPdoMapping(deviceRef, uiPdoMapping);
 * // flatArray will contain tuples like [deviceRef, 0x2012, 0x01]
 * ```
 */
function flattenUiPdoMapping(deviceRef, pdoMapping) {
    const result = [];
    for (const pdoType of ['rx', 'tx']) {
        for (const key in pdoMapping[pdoType]) {
            const entries = pdoMapping[pdoType][key];
            for (const entry of entries) {
                const value = parseInt(entry, 16); // hex string -> number
                const [index, subindex] = parsePdoSubItemValue(value); // ignore bitlen
                result.push([deviceRef, index, subindex]);
            }
        }
    }
    return result;
}
exports.flattenUiPdoMapping = flattenUiPdoMapping;
//# sourceMappingURL=device-parameter.js.map