"use strict";
/*
 * Copyright (c) 2025-2026 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */
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;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.isWindows = isWindows;
exports.isLinux = isLinux;
exports.isMac = isMac;
exports.changeFileExtension = changeFileExtension;
exports.changeDeclgenFileExtension = changeDeclgenFileExtension;
exports.ensurePathExists = ensurePathExists;
exports.ensureDirExists = ensureDirExists;
exports.toUnixPath = toUnixPath;
exports.readFirstLineSync = readFirstLineSync;
exports.safeRealpath = safeRealpath;
exports.getInteropFilePathByApi = getInteropFilePathByApi;
exports.getOhmurlByApi = getOhmurlByApi;
exports.isSubPathOf = isSubPathOf;
exports.getFileExtension = getFileExtension;
exports.hasEntry = hasEntry;
exports.createFileIfNotExists = createFileIfNotExists;
exports.isMixCompileProject = isMixCompileProject;
exports.checkDependencyModuleInfoCorrectness = checkDependencyModuleInfoCorrectness;
exports.computeHash = computeHash;
exports.getFileHash = getFileHash;
exports.formEts2pandaCmd = formEts2pandaCmd;
exports.updateFileHash = updateFileHash;
exports.shouldBeUpdated = shouldBeUpdated;
const crypto = __importStar(require("crypto"));
const fs = __importStar(require("fs"));
const os = __importStar(require("os"));
const path = __importStar(require("path"));
const pre_define_1 = require("../pre_define");
const logger_1 = require("../logger");
const error_1 = require("../util/error");
const types_1 = require("../types");
const WINDOWS = 'Windows_NT';
const LINUX = 'Linux';
const MAC = 'Darwin';
function isWindows() {
    return os.type() === WINDOWS;
}
function isLinux() {
    return os.type() === LINUX;
}
function isMac() {
    return os.type() === MAC;
}
function changeFileExtension(file, targetExt, originExt = '') {
    let currentExt = originExt.length === 0 ? getFileExtension(file) : originExt;
    let fileWithoutExt = file.substring(0, file.lastIndexOf(currentExt));
    return fileWithoutExt + targetExt;
}
function changeDeclgenFileExtension(file, targetExt) {
    if (file.endsWith(pre_define_1.DECL_ETS_SUFFIX)) {
        return changeFileExtension(file, targetExt, pre_define_1.DECL_ETS_SUFFIX);
    }
    return changeFileExtension(file, targetExt);
}
function ensurePathExists(filePath) {
    const dirPath = path.dirname(filePath);
    ensureDirExists(dirPath);
}
function ensureDirExists(dirPath) {
    try {
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath, { recursive: true });
        }
    }
    catch (error) {
        if (error instanceof Error) {
            console.error(`Error: ${error.message}`);
        }
    }
}
function toUnixPath(path) {
    return path.replace(/\\/g, '/');
}
function readFirstLineSync(filePath) {
    const fd = fs.openSync(filePath, 'r');
    const buffer = Buffer.alloc(256);
    const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0);
    fs.closeSync(fd);
    const content = buffer.toString('utf-8', 0, bytesRead);
    const firstLine = content.split(/\r?\n/, 1)[0].trim();
    return firstLine;
}
function safeRealpath(path) {
    try {
        return fs.realpathSync(path);
    }
    catch (error) {
        if (error instanceof Error) {
            throw new error_1.DriverError(logger_1.LogDataFactory.newInstance(error_1.ErrorCode.BUILDSYSTEM_PATH_RESOLVE_FAIL, `Error resolving path "${path}".`, error.message));
        }
        throw error;
    }
}
function getInteropFilePathByApi(apiName, interopSDKPath) {
    for (const sdkPath of interopSDKPath) {
        const modulePath = path.resolve(sdkPath, apiName + pre_define_1.DECL_ETS_SUFFIX);
        if (fs.existsSync(modulePath)) {
            return modulePath;
        }
    }
    return '';
}
/**
 * Issue:26513
 * todo read config from external instead of prodcue
 */
function getOhmurlByApi(api) {
    const REG_SYSTEM_MODULE = new RegExp(`@(${pre_define_1.sdkConfigPrefix})\\.(\\S+)`);
    if (REG_SYSTEM_MODULE.test(api.trim())) {
        return api.replace(REG_SYSTEM_MODULE, (_, moduleType, systemKey) => {
            const systemModule = `${moduleType}.${systemKey}`;
            if (pre_define_1.NATIVE_MODULE.has(systemModule)) {
                return `@native:${systemModule}`;
            }
            else if (moduleType === pre_define_1.ARKTS_MODULE_NAME) {
                // @arkts.xxx -> @ohos:arkts.xxx
                return `@ohos:${systemModule}`;
            }
            else {
                return `@ohos:${systemKey}`;
            }
            ;
        });
    }
    return '';
}
function isSubPathOf(targetPath, parentDir) {
    const resolvedParent = path.posix.resolve(parentDir);
    const resolvedTarget = path.posix.resolve(targetPath);
    return resolvedTarget === resolvedParent || resolvedTarget.startsWith(resolvedParent + '/');
}
/**
 * Get the full extension of a file, supporting composite extensions like '.d.ts', '.test.ts', '.d.ets', etc.
 * @param filePath - File path or file name.
 * @param knownCompositeExts - Optional list of known composite extensions to match against.
 * @returns The full extension (e.g., '.d.ts'). Returns an empty string if no extension is found.
 */
function getFileExtension(filePath, knownCompositeExts = ['.d.ts', '.test.ts', '.d.ets']) {
    const baseName = path.basename(filePath);
    // Match known composite extensions first
    for (const ext of knownCompositeExts) {
        if (baseName.endsWith(ext)) {
            return ext;
        }
    }
    // Fallback to default behavior: return the last segment after the final dot
    return path.extname(baseName);
}
function hasEntry(moduleInfo) {
    switch (moduleInfo.moduleType) {
        case types_1.OHOS_MODULE_TYPE.SHARED:
        case types_1.OHOS_MODULE_TYPE.HAR:
            return true;
        default:
            return false;
    }
}
function createFileIfNotExists(filePath, content) {
    try {
        const normalizedPath = path.normalize(filePath);
        if (fs.existsSync(normalizedPath)) {
            return false;
        }
        ensurePathExists(filePath);
        fs.writeFileSync(normalizedPath, content, { encoding: 'utf-8' });
        return true;
    }
    catch (error) {
        return false;
    }
}
function isMixCompileProject(buildConfig) {
    for (const moduleInfo of buildConfig.dependencyModuleList) {
        if (moduleInfo.language === pre_define_1.LANGUAGE_VERSION.ARKTS_1_1 ||
            moduleInfo.language === pre_define_1.LANGUAGE_VERSION.ARKTS_HYBRID) {
            return true;
        }
    }
    return false;
}
function checkDependencyModuleInfoCorrectness(module) {
    return (module.packageName && module.modulePath && module.sourceRoots && module.entryFile) !== '';
}
function computeHash(str) {
    const hash = crypto.createHash('sha256');
    return hash.update(str).digest('hex');
}
function getFileHash(filePath) {
    return computeHash(fs.readFileSync(filePath, 'utf-8'));
}
function formEts2pandaCmd(fileInfo, isDebug = false, simultaneous = false, decl = false) {
    const ets2pandaCmd = [
        '_',
        '--extension',
        'ets',
        '--arktsconfig',
        fileInfo.arktsConfig
    ];
    if (simultaneous) {
        ets2pandaCmd.push('--simultaneous');
    }
    if (decl) {
        ets2pandaCmd.push('--emit-declaration');
    }
    ets2pandaCmd.push('--output');
    ets2pandaCmd.push(fileInfo.output);
    if (isDebug) {
        ets2pandaCmd.push('--debug-info');
        ets2pandaCmd.push('--opt-level=0');
    }
    ets2pandaCmd.push(fileInfo.input);
    return ets2pandaCmd;
}
function updateFileHash(file, hashCache) {
    const fileHash = getFileHash(file);
    const currHash = hashCache[file];
    if (fileHash === currHash) {
        return false;
    }
    logger_1.Logger.getInstance().printDebug(`file ${file} hash changed: was ${currHash} became ${fileHash}`);
    hashCache[file] = fileHash;
    return true;
}
function shouldBeUpdated(source, target) {
    if (fs.existsSync(target)) {
        const sourceModified = fs.statSync(source).mtimeMs;
        const targetModified = fs.statSync(target).mtimeMs;
        if (sourceModified < targetModified) {
            return false;
        }
    }
    return true;
}
