//
// Copyright 2025 Picovoice Inc.
//
// You may not use this file except in compliance with the license. A copy of the license is located in the "LICENSE"
// file accompanying this source.
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
//
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSystemLibraryPath = exports.getPlatform = void 0;
const fs = require("fs");
const os = require("os");
const path = require("path");
const SYSTEM_LINUX = 'linux';
const SYSTEM_MAC = 'darwin';
const SYSTEM_WINDOWS = 'win32';
const X86_64 = 'x64';
const ARM_32 = 'arm';
const ARM_64 = 'arm64';
const PLATFORM_LINUX = 'linux';
const PLATFORM_MAC = 'mac';
const PLATFORM_RASPBERRY_PI = 'raspberry-pi';
const PLATFORM_WINDOWS = 'windows';
const ARM_CPU_64 = '-aarch64';
const ARM_CPU_CORTEX_A53 = 'cortex-a53';
const ARM_CPU_CORTEX_A72 = 'cortex-a72';
const ARM_CPU_CORTEX_A76 = 'cortex-a76';
const SUPPORTED_NODEJS_SYSTEMS = new Set([
    SYSTEM_LINUX,
    SYSTEM_MAC,
    SYSTEM_WINDOWS,
]);
const LIBRARY_PATH_PREFIX = '../lib/';
const SYSTEM_TO_LIBRARY_PATH = new Map();
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_MAC}/${X86_64}`, `${PLATFORM_MAC}/x86_64/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_MAC}/${ARM_64}`, `${PLATFORM_MAC}/arm64/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${X86_64}`, `${PLATFORM_LINUX}/x86_64/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${ARM_CPU_CORTEX_A53}`, `${PLATFORM_RASPBERRY_PI}/${ARM_CPU_CORTEX_A53}/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${ARM_CPU_CORTEX_A53}${ARM_CPU_64}`, `${PLATFORM_RASPBERRY_PI}/${ARM_CPU_CORTEX_A53}${ARM_CPU_64}/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${ARM_CPU_CORTEX_A72}`, `${PLATFORM_RASPBERRY_PI}/${ARM_CPU_CORTEX_A72}/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${ARM_CPU_CORTEX_A72}${ARM_CPU_64}`, `${PLATFORM_RASPBERRY_PI}/${ARM_CPU_CORTEX_A72}${ARM_CPU_64}/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${ARM_CPU_CORTEX_A76}`, `${PLATFORM_RASPBERRY_PI}/${ARM_CPU_CORTEX_A76}/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_LINUX}/${ARM_CPU_CORTEX_A76}${ARM_CPU_64}`, `${PLATFORM_RASPBERRY_PI}/${ARM_CPU_CORTEX_A76}${ARM_CPU_64}/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_WINDOWS}/${X86_64}`, `${PLATFORM_WINDOWS}/amd64/pv_recorder.node`);
SYSTEM_TO_LIBRARY_PATH.set(`${SYSTEM_WINDOWS}/${ARM_64}`, `${PLATFORM_WINDOWS}/arm64/pv_recorder.node`);
function absoluteLibraryPath(libraryPath) {
    return path.resolve(__dirname, LIBRARY_PATH_PREFIX, libraryPath);
}
function getCpuPart() {
    const cpuInfo = fs.readFileSync('/proc/cpuinfo', 'ascii');
    for (const infoLine of cpuInfo.split('\n')) {
        if (infoLine.includes('CPU part')) {
            const infoLineSplit = infoLine.split(' ');
            return infoLineSplit[infoLineSplit.length - 1].toLowerCase();
        }
    }
    throw new Error(`Unsupported CPU.`);
}
function getLinuxPlatform() {
    const cpuPart = getCpuPart();
    switch (cpuPart) {
        case '0xd03':
        case '0xd08':
        case '0xd0b':
            return PLATFORM_RASPBERRY_PI;
        default:
            throw new Error(`Unsupported CPU: '${cpuPart}'`);
    }
}
function getLinuxMachine(arch) {
    let archInfo = '';
    if (arch === ARM_64) {
        archInfo = ARM_CPU_64;
    }
    const cpuPart = getCpuPart();
    switch (cpuPart) {
        case '0xd03':
            return ARM_CPU_CORTEX_A53 + archInfo;
        case '0xd08':
            return ARM_CPU_CORTEX_A72 + archInfo;
        case '0xd0b':
            return ARM_CPU_CORTEX_A76 + archInfo;
        default:
            throw new Error(`Unsupported CPU: '${cpuPart}'`);
    }
}
function getPlatform() {
    const system = os.platform();
    const arch = os.arch();
    if (system === SYSTEM_MAC && (arch === X86_64 || arch === ARM_64)) {
        return PLATFORM_MAC;
    }
    if (system === SYSTEM_WINDOWS && (arch === X86_64 || arch === ARM_64)) {
        return PLATFORM_WINDOWS;
    }
    if (system === SYSTEM_LINUX) {
        if (arch === X86_64) {
            return PLATFORM_LINUX;
        }
        return getLinuxPlatform();
    }
    throw `System ${system}/${arch} is not supported by this library.`;
}
exports.getPlatform = getPlatform;
function getSystemLibraryPath() {
    const system = os.platform();
    const arch = os.arch();
    if (SUPPORTED_NODEJS_SYSTEMS.has(system)) {
        switch (system) {
            case SYSTEM_MAC: {
                if (arch === X86_64) {
                    return absoluteLibraryPath(SYSTEM_TO_LIBRARY_PATH.get(`${SYSTEM_MAC}/${X86_64}`));
                }
                else if (arch === ARM_64) {
                    return absoluteLibraryPath(SYSTEM_TO_LIBRARY_PATH.get(`${SYSTEM_MAC}/${ARM_64}`));
                }
                break;
            }
            case SYSTEM_LINUX: {
                if (arch === X86_64) {
                    return absoluteLibraryPath(SYSTEM_TO_LIBRARY_PATH.get(`${SYSTEM_LINUX}/${X86_64}`));
                }
                else if (arch === ARM_32 || arch === ARM_64) {
                    const linuxMachine = getLinuxMachine(arch);
                    if (linuxMachine !== null) {
                        return absoluteLibraryPath(SYSTEM_TO_LIBRARY_PATH.get(`${SYSTEM_LINUX}/${linuxMachine}`));
                    }
                    throw new Error(`System ${system}/${arch} is not supported by this library for this CPU.`);
                }
                break;
            }
            case SYSTEM_WINDOWS: {
                if (arch === X86_64 || arch === ARM_64) {
                    return absoluteLibraryPath(SYSTEM_TO_LIBRARY_PATH.get(`${SYSTEM_WINDOWS}/${arch}`));
                }
                break;
            }
            default: {
                throw new Error(`System ${system}/${arch} is not supported by this library.`);
            }
        }
    }
    throw new Error(`System ${system}/${arch} is not supported by this library.`);
}
exports.getSystemLibraryPath = getSystemLibraryPath;
//# sourceMappingURL=platforms.js.map