//  Copyright (c) 2024 Huawei Technologies Co., Ltd.
//  openUBMC is licensed under Mulan PSL v2.
//  You can use this software according to the terms and conditions of the Mulan PSL v2.
//  You may obtain a copy of Mulan PSL v2 at:
//        #  http://license.coscl.org.cn/MulanPSL2
//  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
//  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
//  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//  See the Mulan PSL v2 for more details.
import { IOptions, IValue } from '../storage-interface';
import { VolumeStaticModel } from '../static-data';
import { IStorageRadio } from '../storage-interface';
import { Raid, RaidType } from '../index';

export class Volume {
  private name: [string, string];
  private raidLevel: [string, string];
  private ioSize: [string, string];
  private readPolicy: [string, IOptions | null];
  private writePolicy: [string, IOptions | null];
  private cachePolicy: [string, IOptions | null];
  private bgiEnable: [string, IOptions | null];
  private initType: [string, string];
  private cacheEnable: [string, IValue | null];
  private consistency: [string, string];
  private status: [string, string];
  private capacityBytes: [string, string];
  private sscd: [string, IStorageRadio | null];
  private currentRead: [string, IOptions | null];
  private currentWrite: [string, IOptions | null];
  private currentCache: [string, IOptions | null];
  private accessPolicy: [string, IOptions | null];
  private driveCache: [string, IOptions | null];
  private bootEnable: [string, IStorageRadio | null];
  private osDriveName: [string, string];
  private fgiProgress: [string, string];
  private twoCache: boolean;
  private url: string;
  private stripeSizeBytes: [string, IOptions | null];
  private accelerationMethod: [string, IOptions | null];
  private cacheLineSize: [string, string | null];
  private bootPriority: [string, IOptions | null];
  private capacity: string | null;
  private capacityUnit: IOptions | null;
  private maxCapacity: number;
  private maxCapacityUnit: IOptions;
  private modifyingCapacity: boolean;
  private construction: [string, string | null];
  private associatedVolumes: [string, string | null];

  constructor(
    name: string,
    raidLevel: string,
    ioSize: string,
    readPolicy: string,
    writePolicy: string,
    cachePolicy: string,
    bgiEnable: boolean,
    initType: string,
    cacheEnable: IValue,
    consistency: string,
    status: string,
    capacityBytes: string,
    sscd: boolean,
    currentRead: string,
    currentWrite: string,
    currentCache: string,
    accessPolicy: string,
    driveCache: string,
    bootEnable: boolean,
    osDriveName: string,
    fgiProgress: string,
    twoCache: boolean,
    url: string,
    raidType: string,
    stripeSizeBytes: number,
    accelerationMethod: string,
    bootPriority: string,
    capacity: string,
    capacityUnit: IOptions | null,
    maxCapacity: number,
    maxCapacityUnit: IOptions,
    modifyingCapacity: boolean,
    cacheLineSize: string,
    construction: string,
    associatedVolumes: string,
  ) {
    this.name = ['COMMON_NAME', name];
    this.raidLevel = ['STORE_RAI_LEVEL', raidLevel];
    this.ioSize = ['STORE_STRIPE_SIZE', ioSize];
    this.status = ['STATUS', status];
    this.capacityBytes = ['COMMON_CAPACITY', capacityBytes];
    this.bootEnable = ['STORE_BOOT_DISK', VolumeStaticModel.getIsBootDisk(bootEnable)];
    this.osDriveName = ['SYSTEM_DRIVE', osDriveName];
    this.fgiProgress = ['SYSTEM_FGIPROGRESS', fgiProgress];
    this.twoCache = twoCache;
    this.currentWrite = [
      'STORE_CURRENT_WRITE_POLICY',
      VolumeStaticModel.getWritePolicy(currentWrite),
    ];
    this.writePolicy = ['STORE_DEFAULT_WRITE', VolumeStaticModel.getWritePolicy(writePolicy)];

    this.readPolicy = ['', null];
    this.cachePolicy = ['', null];
    this.bgiEnable = ['', null];
    this.initType = ['', ''];
    this.cacheEnable = ['', null];
    this.consistency = ['', ''];
    this.currentRead = ['', null];
    this.currentCache = ['', null];
    this.accessPolicy = ['', null];
    this.driveCache = ['', null];
    this.sscd = ['', null];
    this.accelerationMethod = ['', null];
    this.stripeSizeBytes = ['', null];
    this.bootPriority = ['', null];
    this.capacity = capacity;
    this.capacityUnit = capacityUnit;
    this.cacheLineSize = ['', null];
    this.construction = ['', null];
    this.associatedVolumes = ['', null];
    this.maxCapacity = maxCapacity;
    this.maxCapacityUnit = maxCapacityUnit;
    this.modifyingCapacity = modifyingCapacity;
    // 只有BRCM卡才显示属性
    if (raidType === RaidType.BRCM) {
      this.cacheEnable = ['STORE_LEVEL2_CACHE', cacheEnable];
      this.sscd = ['STORE_SSCD_FEATURES', VolumeStaticModel.getSSCDFunction(sscd)];
      this.initType = ['STORE_INITITYPE', this.getInitMode(initType)];
      this.consistency = ['STORE_CONSISTENCY_CHECK', consistency];
      this.readPolicy = ['STORE_DEFAULT_READ', VolumeStaticModel.getReadPolicy(readPolicy)];
      this.writePolicy = ['STORE_DEFAULT_WRITE', VolumeStaticModel.getWritePolicy(writePolicy)];
      this.cachePolicy = ['STORE_DEFAULT_IO', VolumeStaticModel.getIOPolicy(cachePolicy)];
      this.bgiEnable = ['STORE_INITIALIZATION', VolumeStaticModel.getBgiState(bgiEnable)];
      this.currentRead = [
        'STORE_CURRENT_READ_POLICY',
        VolumeStaticModel.getReadPolicy(currentRead),
      ];
      this.currentCache = ['STORE_CURRENT_IQ_POLICY', VolumeStaticModel.getIOPolicy(currentCache)];
      this.accessPolicy = ['STORE_ACCESS_POLICY', VolumeStaticModel.getAccessPolicy(accessPolicy)];
      this.driveCache = ['STORE_CACHE_STATUS', VolumeStaticModel.getDriverCachePolicy(driveCache)];
    } else if (raidType === RaidType.ARIES) {
      this.readPolicy = ['STORE_DEFAULT_READ', VolumeStaticModel.getReadPolicy(readPolicy)];
      this.cachePolicy = ['STORE_DEFAULT_IO', VolumeStaticModel.getIOPolicy(cachePolicy)];
      this.bgiEnable = ['STORE_INITIALIZATION', VolumeStaticModel.getBgiState(bgiEnable)];
      this.currentRead = [
        'STORE_CURRENT_READ_POLICY',
        VolumeStaticModel.getReadPolicy(currentRead),
      ];
      this.currentCache = ['STORE_CURRENT_IQ_POLICY', VolumeStaticModel.getIOPolicy(currentCache)];
      this.accessPolicy = ['STORE_ACCESS_POLICY', VolumeStaticModel.getAccessPolicy(accessPolicy)];
      this.driveCache = ['STORE_CACHE_STATUS', VolumeStaticModel.getDriverCachePolicy(driveCache)];
    } else if (raidType === RaidType.PMC || raidType === RaidType.HBA) {
      this.cacheEnable = ['STORE_LEVEL2_CACHE', cacheEnable];
      this.accelerationMethod = ['STORE_ACCELERATION', VolumeStaticModel.getSpeedMethod(accelerationMethod)];
      this.stripeSizeBytes = ['STORE_STRIPE_SIZE', VolumeStaticModel.getStripeSizeBytes(stripeSizeBytes)];
      this.sscd = ['STORE_SSCD_FEATURES', VolumeStaticModel.getSSCDFunction(sscd)];
      this.cacheLineSize = ['STORE_CACHE_LINE', cacheLineSize];
      this.bootPriority = ['STORE_BOOT_DISK', VolumeStaticModel.getBootPriority(bootPriority)];
      this.currentWrite = [
        'STORE_CURRENT_WRITE_POLICY',
        twoCache ? VolumeStaticModel.getWritePolicy(currentWrite) : null,
      ];
      this.construction = ['FDM_CONSTRUCTION_STATE', construction];
      this.associatedVolumes = ['STORE_ASSOCIT_LOGIC', associatedVolumes];
    } else {
      this.cacheEnable = ['STORE_LEVEL2_CACHE', cacheEnable];
      this.sscd = ['STORE_SSCD_FEATURES', VolumeStaticModel.getSSCDFunction(sscd)];
      this.cacheLineSize = ['STORE_CACHE_LINE', cacheLineSize];
      this.currentWrite = [
        'STORE_CURRENT_WRITE_POLICY',
        twoCache ? VolumeStaticModel.getWritePolicy(currentWrite) : null,
      ];
      this.construction = ['FDM_CONSTRUCTION_STATE', construction];
      this.associatedVolumes = ['STORE_ASSOCIT_LOGIC', associatedVolumes];
    }
    this.url = url;
  }

  get getStripeSizeBytes(): IOptions | null {
    return this.stripeSizeBytes[1];
  }

  get getBootPriority(): IOptions | null {
    return this.bootPriority[1];
  }

  get getPMCWritePolicy(): IOptions | null {
    return this.writePolicy[1];
  }

  get getMaxCapacity(): number {
    return this.maxCapacity;
  }

  get getMaxCapacityUnit(): IOptions {
    return this.maxCapacityUnit;
  }

  get getModifyingCapacity(): boolean {
    return this.modifyingCapacity;
  }

  get getCapacity(): string | null {
    return this.capacity;
  }

  get getCapacityUnit(): IOptions | null {
    return this.capacityUnit;
  }

  get getSpeedMethod(): IOptions | null {
    return this.accelerationMethod[1];
  }

  private getInitMode(key: string): string {
    let str = '--';
    switch (key) {
      case 'UnInit':
        str = 'No Init';
        break;
      case 'QuickInit':
        str = 'Quick Init';
        break;
      case 'FullInit':
        str = 'Full Init';
        break;
      default:
        str = '--';
    }
    return str;
  }

  get getName(): string {
    return this.name[1];
  }

  get getBootDisk(): IStorageRadio | null {
    return this.bootEnable[1];
  }

  get getSSCDFunc(): IStorageRadio | null {
    return this.sscd[1];
  }

  get getDriveCache(): IOptions | null {
    return this.driveCache[1];
  }

  get getAccessPolicy(): IOptions | null {
    return this.accessPolicy[1];
  }

  get getBGIState(): IOptions | null {
    return this.bgiEnable[1];
  }

  get getIOPolicy(): IOptions | null {
    return this.cachePolicy[1];
  }

  get getWritePolicy(): IOptions | null {
    return this.writePolicy[1];
  }

  get getReadPolicy(): IOptions | null {
    return this.readPolicy[1];
  }

  get getCacheEnableState(): boolean {
    return Boolean(this?.cacheEnable[1]?.value);
  }

  get getTwoCache(): boolean {
    return this.twoCache;
  }
  
  get getURL(): string {
    return this.url;
  }
}
