//  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 } from '../storage-interface';
import { IVolumeEditData, IVolumnDisabled, IStorageRadio } from '../storage-interface';
import { StorageTree } from '../storage-tree.model';
import { VolumeStaticModel } from '../static-data';

export class VolumeEditModel {
  private constructor() { }

  private static instance: VolumeEditModel | null;

  private writePolicyOption = VolumeStaticModel.writePolicy;
  private selectData: IVolumeEditData = {
    name: null,
    bootEnabled: null,
    sSDCachingEnabled: null,
    driveCachePolicy: null,
    accessPolicy: null,
    bGIEnabled: null,
    defaultCachePolicy: null,
    defaultWritePolicy: null,
    defaultReadPolicy: null,
    optimumIOSizeBytes: null,
    accelerationMethod: null,
    capacity: null,
    capacityUnit: null,
    bootPriority: null,
  };
  
  private originData!: IVolumeEditData;
  private volumnDisable: IVolumnDisabled = {
    twoCache: true,
    readPolicyConfig: true,
    writePolicyConfig: true,
    iOPolicyConfig: true,
    drivePolicyConfig: true,
    accessPolicyConfig: true,
    isSSCD: true,
  };

  private saveState!: boolean;
  // hi1880卡模式为HBA时，逻辑盘设置项“默认读策略”和“默认读策略”置灰
  public hbaMode: boolean = false;
  public static getInstance(): VolumeEditModel {
    if (!VolumeEditModel.instance) {
      VolumeEditModel.instance = new VolumeEditModel();
    }
    return VolumeEditModel.instance;
  }

  get getWritePolicy() {
    return this.writePolicyOption;
  }

  get getOriginData() {
    return this.originData;
  }

  get getSelectData() {
    return this.selectData;
  }

  get getSaveState(): boolean {
    return this.saveState;
  }

  get getVolumnDisable(): IVolumnDisabled {
    return this.volumnDisable;
  }


  set setOriginData(selectData: IVolumeEditData) {
    this.originData = selectData;
  }

  public static initVolumeEdit(
    name: string,
    bootDiskSelect: IStorageRadio,
    sscdFuncSelect: IStorageRadio,
    driveCacheSelect: IOptions,
    accessSelect: IOptions,
    bgiStateSelect: IOptions,
    ioPolicySelect: IOptions,
    writePolicySelect: IOptions,
    readPolicySelect: IOptions,
    ssdEnable: boolean,
    twoCache: boolean,
    raidIndex: number,
    hbaMode: boolean,
    optimumIOSizeBytes: IOptions,
    accelerationMethod: IOptions,
    capacity: string,
    capacityUnit: IOptions,
    bootPriority: IOptions,
  ): VolumeEditModel | null {
    VolumeEditModel.getInstance().selectData = {
      name: name,
      bootEnabled: bootDiskSelect,
      sSDCachingEnabled: sscdFuncSelect,
      driveCachePolicy: driveCacheSelect,
      accessPolicy: accessSelect,
      bGIEnabled: bgiStateSelect,
      defaultCachePolicy: ioPolicySelect,
      defaultWritePolicy: writePolicySelect,
      defaultReadPolicy: readPolicySelect,
      optimumIOSizeBytes,
      accelerationMethod,
      capacity,
      capacityUnit,
      bootPriority,
    };
    VolumeEditModel.getInstance().hbaMode = hbaMode;
    const raidChildData = StorageTree.getInstance().getParentRaid(raidIndex).getRaid.getChidrenData;
    VolumeEditModel.getInstance().volumnDisable = {
      twoCache,
      readPolicyConfig: twoCache ? twoCache : !raidChildData.readPolicyConfig,
      writePolicyConfig: !raidChildData.writePolicyConfig,
      iOPolicyConfig: twoCache ? twoCache : !raidChildData.IOPolicyConfig,
      drivePolicyConfig: twoCache ? twoCache : !raidChildData.drivePolicyConfig,
      accessPolicyConfig: twoCache ? twoCache : !raidChildData.accessPolicyConfig,
      isSSCD: !!sscdFuncSelect,
    };
    VolumeEditModel.getInstance().originData = JSON.parse(JSON.stringify(VolumeEditModel.getInstance().getSelectData));
    VolumeEditModel.getInstance().checkSave();
    if (twoCache) {
      VolumeEditModel.getInstance().writePolicyOption = [
        VolumeStaticModel.writePolicy[0],
        VolumeStaticModel.writePolicy[1],
      ];
    }
    return this.instance;
  }

  public static destroy(): void {
    if (VolumeEditModel.instance) {
      VolumeEditModel.instance = null;
    }
  }

  public setName(name: string) {
    this.selectData.name = name;
    this.checkSave();
  }

  public setBootDisk(bootDisk: IStorageRadio) {
    this.selectData.bootEnabled = bootDisk;
    this.checkSave();
  }

  public setSSCDFunc(sscdFunc: IStorageRadio) {
    this.selectData.sSDCachingEnabled = sscdFunc;
    this.checkSave();
  }

  public setDriveCache(driveCache: IOptions) {
    this.selectData.driveCachePolicy = driveCache;
    this.checkSave();
  }

  public setAccess(access: IOptions) {
    this.selectData.accessPolicy = access;
    this.checkSave();
  }

  public setBgiState(bgiState: IOptions) {
    this.selectData.bGIEnabled = bgiState;
    this.checkSave();
  }

  public setIOPolicy(ioPolicy: IOptions) {
    this.selectData.defaultCachePolicy = ioPolicy;
    this.checkSave();
  }

  public setWritePolicy(writePolicy: IOptions) {
    this.selectData.defaultWritePolicy = writePolicy;
    this.checkSave();
  }

  public setReadPolicy(readPolicy: IOptions) {
    this.selectData.defaultReadPolicy = readPolicy;
    this.checkSave();
  }

  public setBootPriority(bootPriority: IOptions): void {
    this.selectData.bootPriority = bootPriority;
    this.checkSave();
  }

  public setStripeSizeBytes(size: IOptions): void {
    this.selectData.optimumIOSizeBytes = size;
    this.checkSave();
  }

  public setSpeedMethod(method: IOptions): void {
    this.selectData.accelerationMethod = method;
    this.checkSave();
  }

  public setCapacity(capacity: string): void {
    this.selectData.capacity = capacity;
    this.checkSave();
  }

  public setCapacityUnit(unit: IOptions): void {
    this.selectData.capacityUnit = unit;
    this.checkSave();
  }

  public checkSave() {
    if (
      JSON.stringify(this.originData) === JSON.stringify(this.selectData)
    ) {
      this.saveState = true;
    } else {
      this.saveState = false;
    }
  }
}
