"use strict";
/**
 * This module's only purpose is to build the models index for zigbee-herdsman-converters.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildIndex = buildIndex;
const node_fs_1 = require("node:fs");
const node_path_1 = __importDefault(require("node:path"));
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
/**
 * Format:
 * Record<(zigbeeModel | fingerprint.modelID), [JS file name, index in `definitions` export][]>
 *
 * Note: `null` is a valid key (assigned for any `undefined` model).
 *
 * Example:
 * ```json
 * {
 *     "vzm31-sn": [["inovelli.js", 1]],
 *     "null": [["yale.js", 25], ["tuya.js", 172]]
 * }
 * ```
 */
const lookup = {};
function addToLookup(zigbeeModel, index) {
    zigbeeModel = zigbeeModel ? zigbeeModel.toLowerCase() : null;
    if (!lookup[zigbeeModel]) {
        lookup[zigbeeModel] = [];
    }
    if (!lookup[zigbeeModel].some((z) => z[0] === index[0] && z[1] === index[1])) {
        lookup[zigbeeModel].splice(0, 0, index);
    }
}
async function buildIndex(fromSrc = false) {
    let totalDefinitions = 0;
    // keep track of added stuff to check for dupes
    const addedFingerprints = [];
    const addedZigbeeModels = [];
    const addedModels = [];
    const devicesDir = fromSrc ? node_path_1.default.join("src", "devices") : node_path_1.default.join("dist", "devices");
    for (const moduleName of (0, node_fs_1.readdirSync)(devicesDir)) {
        if (moduleName === (fromSrc ? "index.ts" : "index.js") || !moduleName.endsWith(fromSrc ? ".ts" : ".js")) {
            continue;
        }
        const filePath = node_path_1.default.join(devicesDir, moduleName);
        const { definitions } = (await Promise.resolve(`${`./devices/${moduleName.slice(0, -3)}`}`).then(s => __importStar(require(s))));
        console.log(`Processing ${filePath}, ${definitions.length} converters`);
        for (let i = 0; i < definitions.length; i++) {
            const definition = definitions[i];
            if (addedModels.includes(definition.model.toLowerCase())) {
                throw new Error(`Duplicate model ${definition.model}`);
            }
            addedModels.push(definition.model.toLowerCase());
            if (definition.whiteLabel) {
                for (const whiteLabel of definition.whiteLabel) {
                    if ("fingerprint" in whiteLabel) {
                        if (addedModels.includes(whiteLabel.model.toLowerCase())) {
                            if (whiteLabel.vendor === definition.vendor) {
                                throw new Error(`Duplicate whitelabel model ${whiteLabel.model}`);
                            }
                        }
                        else {
                            addedModels.push(whiteLabel.model.toLowerCase());
                        }
                    }
                }
            }
            if (definition.fingerprint) {
                for (const fingerprint of definition.fingerprint) {
                    for (const addedFingerprint of addedFingerprints) {
                        if ((0, fast_deep_equal_1.default)(addedFingerprint, fingerprint)) {
                            throw new Error(`Duplicate fingerprint for ${definition.model}: ${JSON.stringify(fingerprint)}`);
                        }
                    }
                    // type `modelID?: string;` means modelID can be undefined, ends up under index "null"
                    addToLookup(fingerprint.modelID, [moduleName, i]);
                    addedFingerprints.push(fingerprint);
                }
            }
            if (definition.zigbeeModel) {
                for (const zigbeeModel of definition.zigbeeModel) {
                    if (addedZigbeeModels.includes(zigbeeModel.toLowerCase())) {
                        throw new Error(`Duplicate zigbee model ${zigbeeModel}`);
                    }
                    addToLookup(zigbeeModel, [moduleName, i]);
                    addedZigbeeModels.push(zigbeeModel.toLowerCase());
                }
            }
        }
        totalDefinitions += definitions.length;
    }
    const target = fromSrc ? "models-index.json" : node_path_1.default.join("dist", "models-index.json");
    (0, node_fs_1.writeFileSync)(target, JSON.stringify(lookup), "utf8");
    console.log(`\nProcessed ${totalDefinitions} definitions`);
}
if (require.main === module) {
    void buildIndex();
}
//# sourceMappingURL=indexer.js.map