/*
 * Copyright (c) 2024 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.
 */

import { HiLog } from '../base/HiLog';
import FileUtil from '../external/FileUtil';
import { dlpPermission } from '@kit.DataProtectionKit';
import fs from '@ohos.file.fs';
import CommonUtil from '../base/CommonUtil';

const TAG = 'FileUtils';

export interface FileMsg {
  fileName: string;
  filePath: string;
  fileType: string;
}

export default class FileUtils {
  public static readonly FILE_ID_ANONYMIZED_SUFFIX_LENGTH: number = 8;
  public static readonly FILE_NAME_ANONYMIZED_SUFFIX_LENGTH: number = 8;

  static getSuffixFileMsgByUri(uri: string): FileMsg {
    let strArray: string[] = uri.split('/');
    let len: number = strArray.length;
    let fileName: string = strArray[len - 1];
    let filePath: string = strArray.slice(0, len - 1).join('/');
    let pointIndex: number = fileName.lastIndexOf('.');
    if (pointIndex < 0) {
      pointIndex = fileName.length;
    }
    let fileType: string = fileName.slice(pointIndex, fileName.length);
    let result: FileMsg = {
      fileName: fileName.slice(0, pointIndex),
      filePath: filePath,
      fileType: fileType,
    };
    return result;
  }

  static getAllSuffixByUri(uri: string): FileMsg {
    let strArray: string[] = uri.split('/');
    let len: number = strArray.length;
    let fileName: string = strArray[len - 1];
    let filePath: string = strArray.slice(0, len - 1).join('/');
    let lastIndex: number = fileName.lastIndexOf('.');
    let secondIndex: number = fileName.lastIndexOf('.', lastIndex - 1);
    let fileType: string = fileName.substring(secondIndex + 1, lastIndex);
    let result: FileMsg = {
      fileName: fileName.substring(0, secondIndex),
      filePath: filePath,
      fileType: fileType,
    };
    return result;
  }

  static getFileMsgByFileName(fileName: string): string {
    let lastIndex: number = fileName.lastIndexOf('.');
    let secondIndex: number = fileName.lastIndexOf('.', lastIndex - 1);
    fileName = fileName.substring(0, secondIndex);
    return fileName;
  }

  static isDLPFile(uri: string) {
    return new Promise<boolean>(async (resolve, reject) => {
      let file: fs.File | undefined;
      try {
        file = fs.openSync(uri);
        try {
          let res = await dlpPermission.isDLPFile(file.fd);
          resolve(res);
        } catch (err) {
          HiLog.wrapError(TAG, err, 'isDLPFile error');
          reject(err);
        }
      } catch (err) {
        HiLog.wrapError(TAG, err, 'openSync error');
        reject(err);
      } finally {
        if (file) {
          FileUtil.closeSync(file);
        }
      }
    })
  }

  static removeFileTypeFirstDot(str: string) {
    return str.trim().replace(/^\./, '');
  }

  public static anonymizedFileName(fileName: string): string {
    if (CommonUtil.isEmptyStr(fileName)) {
      return '';
    }
    if (fileName.length <= FileUtils.FILE_NAME_ANONYMIZED_SUFFIX_LENGTH) {
      return '****';
    }
    const anonymized = fileName.substring(0, FileUtils.FILE_NAME_ANONYMIZED_SUFFIX_LENGTH) +
    '*'.repeat(fileName.length - FileUtils.FILE_NAME_ANONYMIZED_SUFFIX_LENGTH);
    return anonymized;
  }

  public static anonymizedFileId(fileId: string): string {
    if (CommonUtil.isEmptyStr(fileId)) {
      return '';
    }
    if (fileId.length <= FileUtils.FILE_ID_ANONYMIZED_SUFFIX_LENGTH) {
      return fileId;
    }
    const anonymized = '*'.repeat(fileId.length - FileUtils.FILE_ID_ANONYMIZED_SUFFIX_LENGTH) +
    fileId.substring(fileId.length - FileUtils.FILE_ID_ANONYMIZED_SUFFIX_LENGTH);
    return anonymized;
  }

  public static getAnonymizedFilenameByUri(uri: string): string {
    if (CommonUtil.isEmptyStr(uri)) {
      return '';
    }
    const strArray: string[] = uri.split('/');
    return FileUtils.anonymizedFileName(strArray[strArray.length - 1]);
  }

  static getFileSuffixByFileName(fileName: string): string {
    let lastIndex: number = fileName.lastIndexOf('.');
    let fileSuffix: string = fileName.substring(lastIndex + 1, fileName.length);
    return fileSuffix;
  }

  static getParamOrDefault<T>(params: Record<string, Object> | undefined, key: string, defaultValue: T): T {
    if (!params) {
      HiLog.error(TAG, 'getParamOrDefault params null');
      return defaultValue;
    }
    const value = params[key];
    return (typeof value === typeof defaultValue) ? value as T : defaultValue;
  }

  static getExtractRealType(typeStr: string): string {
    const lastUnderscore = typeStr.lastIndexOf('_');
    if (lastUnderscore === -1) {
      return typeStr;
    }
    return typeStr.substring(lastUnderscore + 1);
  }
}