13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ciimport { existsSync, readFileSync, writeFileSync } from 'fs';
173af6ab5fSopenharmony_ciimport { readJsonSync } from 'fs-extra';
183af6ab5fSopenharmony_ciimport type { IOptions } from '../configs/IOptions';
193af6ab5fSopenharmony_ciimport { fileExtensions } from '../common/type';
203af6ab5fSopenharmony_ciimport type { PathAndExtension } from '../common/type';
213af6ab5fSopenharmony_ciimport fs from 'fs';
223af6ab5fSopenharmony_ciimport path from 'path';
233af6ab5fSopenharmony_ci
243af6ab5fSopenharmony_ciexport const BUNDLE = '@bundle:';
253af6ab5fSopenharmony_ciexport const NORMALIZE = '@normalized:';
263af6ab5fSopenharmony_ci
273af6ab5fSopenharmony_ciexport class FileUtils {
283af6ab5fSopenharmony_ci  /**
293af6ab5fSopenharmony_ci   * Read file and return content
303af6ab5fSopenharmony_ci   *
313af6ab5fSopenharmony_ci   * @param filePath file path
323af6ab5fSopenharmony_ci   */
333af6ab5fSopenharmony_ci  public static readFile(filePath: string): string | undefined {
343af6ab5fSopenharmony_ci    if (!existsSync(filePath)) {
353af6ab5fSopenharmony_ci      console.error(`File <${this.getFileName(filePath)}> is not found.`);
363af6ab5fSopenharmony_ci      return undefined;
373af6ab5fSopenharmony_ci    }
383af6ab5fSopenharmony_ci    return readFileSync(filePath, 'utf-8');
393af6ab5fSopenharmony_ci  }
403af6ab5fSopenharmony_ci
413af6ab5fSopenharmony_ci  /**
423af6ab5fSopenharmony_ci   * Read file and convert to json object.
433af6ab5fSopenharmony_ci   *
443af6ab5fSopenharmony_ci   * @param filePath file path
453af6ab5fSopenharmony_ci   */
463af6ab5fSopenharmony_ci  public static readFileAsJson(filePath: string): IOptions | undefined {
473af6ab5fSopenharmony_ci    if (!existsSync(filePath)) {
483af6ab5fSopenharmony_ci      console.error(`File <${this.getFileName(filePath)}> is not found.`);
493af6ab5fSopenharmony_ci      return undefined;
503af6ab5fSopenharmony_ci    }
513af6ab5fSopenharmony_ci
523af6ab5fSopenharmony_ci    try {
533af6ab5fSopenharmony_ci      return readJsonSync(filePath);
543af6ab5fSopenharmony_ci    } catch (e) {
553af6ab5fSopenharmony_ci      console.error('json file read error: ' + filePath);
563af6ab5fSopenharmony_ci      return undefined;
573af6ab5fSopenharmony_ci    }
583af6ab5fSopenharmony_ci  }
593af6ab5fSopenharmony_ci
603af6ab5fSopenharmony_ci  /**
613af6ab5fSopenharmony_ci   * Get File Name
623af6ab5fSopenharmony_ci   *
633af6ab5fSopenharmony_ci   * @param filePath file path
643af6ab5fSopenharmony_ci   */
653af6ab5fSopenharmony_ci  public static getFileName(filePath: string): string | undefined {
663af6ab5fSopenharmony_ci    if (!filePath) {
673af6ab5fSopenharmony_ci      return undefined;
683af6ab5fSopenharmony_ci    }
693af6ab5fSopenharmony_ci
703af6ab5fSopenharmony_ci    const lastSepIndex: number = filePath.lastIndexOf('/');
713af6ab5fSopenharmony_ci    if (lastSepIndex >= 0) {
723af6ab5fSopenharmony_ci      return filePath.slice(lastSepIndex + 1);
733af6ab5fSopenharmony_ci    }
743af6ab5fSopenharmony_ci
753af6ab5fSopenharmony_ci    return filePath.slice(filePath.lastIndexOf('\\') + 1);
763af6ab5fSopenharmony_ci  }
773af6ab5fSopenharmony_ci
783af6ab5fSopenharmony_ci  /**
793af6ab5fSopenharmony_ci   * Get suffix of a file.
803af6ab5fSopenharmony_ci   *
813af6ab5fSopenharmony_ci   * @param filePath file path
823af6ab5fSopenharmony_ci   */
833af6ab5fSopenharmony_ci  public static getFileExtension(filePath: string): string | undefined {
843af6ab5fSopenharmony_ci    if (!filePath || !filePath.includes('.')) {
853af6ab5fSopenharmony_ci      return undefined;
863af6ab5fSopenharmony_ci    }
873af6ab5fSopenharmony_ci
883af6ab5fSopenharmony_ci    // get file name
893af6ab5fSopenharmony_ci    let fileName: string = this.getFileName(filePath);
903af6ab5fSopenharmony_ci    if (!fileName.includes('.')) {
913af6ab5fSopenharmony_ci      return undefined;
923af6ab5fSopenharmony_ci    }
933af6ab5fSopenharmony_ci
943af6ab5fSopenharmony_ci    return fileName.slice(fileName.lastIndexOf('.') + 1);
953af6ab5fSopenharmony_ci  }
963af6ab5fSopenharmony_ci
973af6ab5fSopenharmony_ci  public static writeFile(filePath: string, content: string): void {
983af6ab5fSopenharmony_ci    writeFileSync(filePath, content);
993af6ab5fSopenharmony_ci  }
1003af6ab5fSopenharmony_ci
1013af6ab5fSopenharmony_ci  /**
1023af6ab5fSopenharmony_ci   * get prefix of directory
1033af6ab5fSopenharmony_ci   * @param dirPath
1043af6ab5fSopenharmony_ci   */
1053af6ab5fSopenharmony_ci  public static getPrefix(dirPath: string): string | undefined {
1063af6ab5fSopenharmony_ci    if (!dirPath || (!dirPath.includes('/') && !dirPath.includes('\\'))) {
1073af6ab5fSopenharmony_ci      return undefined;
1083af6ab5fSopenharmony_ci    }
1093af6ab5fSopenharmony_ci
1103af6ab5fSopenharmony_ci    const sepIndex: number = dirPath.lastIndexOf('/');
1113af6ab5fSopenharmony_ci    if (sepIndex >= 0) {
1123af6ab5fSopenharmony_ci      return dirPath.slice(0, sepIndex + 1);
1133af6ab5fSopenharmony_ci    }
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_ci    return dirPath.slice(0, dirPath.lastIndexOf('\\') + 1);
1163af6ab5fSopenharmony_ci  }
1173af6ab5fSopenharmony_ci
1183af6ab5fSopenharmony_ci  public static getPathWithoutPrefix(filePath: string, prefix: string): string | undefined {
1193af6ab5fSopenharmony_ci    if (!filePath.startsWith(prefix)) {
1203af6ab5fSopenharmony_ci      return filePath;
1213af6ab5fSopenharmony_ci    }
1223af6ab5fSopenharmony_ci
1233af6ab5fSopenharmony_ci    return filePath.slice(prefix.length);
1243af6ab5fSopenharmony_ci  }
1253af6ab5fSopenharmony_ci
1263af6ab5fSopenharmony_ci  public static splitFilePath(filePath: string): string[] {
1273af6ab5fSopenharmony_ci    if (!filePath.includes('\\') && !filePath.includes('\/')) {
1283af6ab5fSopenharmony_ci      return [filePath];
1293af6ab5fSopenharmony_ci    }
1303af6ab5fSopenharmony_ci    const directories = filePath.split(/[\/\\]/);
1313af6ab5fSopenharmony_ci    return directories;
1323af6ab5fSopenharmony_ci  }
1333af6ab5fSopenharmony_ci
1343af6ab5fSopenharmony_ci  /**
1353af6ab5fSopenharmony_ci   * split the file path and collect the results into the reserved array
1363af6ab5fSopenharmony_ci   */
1373af6ab5fSopenharmony_ci  public static collectPathReservedString(filePath: string, reservedArray: string[]): void {
1383af6ab5fSopenharmony_ci    const directories = this.splitFilePath(filePath);
1393af6ab5fSopenharmony_ci    directories.forEach(reservedStr => {
1403af6ab5fSopenharmony_ci      reservedArray.push(reservedStr);
1413af6ab5fSopenharmony_ci    });
1423af6ab5fSopenharmony_ci  }
1433af6ab5fSopenharmony_ci
1443af6ab5fSopenharmony_ci  static relativePathBegins: string[] = ['./', '../', '.\\', '..\\'];
1453af6ab5fSopenharmony_ci  public static isRelativePath(filePath: string): boolean {
1463af6ab5fSopenharmony_ci    for (const bebin of this.relativePathBegins) {
1473af6ab5fSopenharmony_ci      if (filePath.startsWith(bebin)) {
1483af6ab5fSopenharmony_ci        return true;
1493af6ab5fSopenharmony_ci      }
1503af6ab5fSopenharmony_ci    }
1513af6ab5fSopenharmony_ci    return false;
1523af6ab5fSopenharmony_ci  }
1533af6ab5fSopenharmony_ci
1543af6ab5fSopenharmony_ci  public static getFileSuffix(filePath: string): PathAndExtension {
1553af6ab5fSopenharmony_ci    for (let ext of fileExtensions) {
1563af6ab5fSopenharmony_ci      if (filePath.endsWith(ext)) {
1573af6ab5fSopenharmony_ci        const filePathWithoutSuffix: string = filePath.replace(new RegExp(`${ext}$`), '');
1583af6ab5fSopenharmony_ci        return { path: filePathWithoutSuffix, ext: ext };
1593af6ab5fSopenharmony_ci      }
1603af6ab5fSopenharmony_ci    }
1613af6ab5fSopenharmony_ci    return { path: filePath, ext: '' };
1623af6ab5fSopenharmony_ci  }
1633af6ab5fSopenharmony_ci
1643af6ab5fSopenharmony_ci  public static isReadableFile(filePath: string): boolean {
1653af6ab5fSopenharmony_ci    try {
1663af6ab5fSopenharmony_ci      fs.accessSync(filePath, fs.constants.R_OK);
1673af6ab5fSopenharmony_ci    } catch (err) {
1683af6ab5fSopenharmony_ci      return false;
1693af6ab5fSopenharmony_ci    }
1703af6ab5fSopenharmony_ci    return true;
1713af6ab5fSopenharmony_ci  }
1723af6ab5fSopenharmony_ci
1733af6ab5fSopenharmony_ci  public static toUnixPath(data: string): string {
1743af6ab5fSopenharmony_ci    if (/^win/.test(require('os').platform())) {
1753af6ab5fSopenharmony_ci      const fileTmps: string[] = data.split(path.sep);
1763af6ab5fSopenharmony_ci      const newData: string = path.posix.join(...fileTmps);
1773af6ab5fSopenharmony_ci      return newData;
1783af6ab5fSopenharmony_ci    }
1793af6ab5fSopenharmony_ci    return data;
1803af6ab5fSopenharmony_ci  }
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci  public static getAbsPathBaseConfigPath(configPath: string, relativePath: string): string {
1833af6ab5fSopenharmony_ci    const absPath: string = path.join(path.dirname(configPath), relativePath);
1843af6ab5fSopenharmony_ci    return this.toUnixPath(absPath);
1853af6ab5fSopenharmony_ci  }
1863af6ab5fSopenharmony_ci
1873af6ab5fSopenharmony_ci  public static deleteFile(filePath: string): void {
1883af6ab5fSopenharmony_ci    if (fs.existsSync(filePath)) {
1893af6ab5fSopenharmony_ci        fs.unlinkSync(filePath);
1903af6ab5fSopenharmony_ci    }
1913af6ab5fSopenharmony_ci  }
1923af6ab5fSopenharmony_ci}
193