//  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 { IRaidEditData, Store } from '../storage-interface';
import { IOptions } from '../storage-interface';


export class RaidEditModel {
  private constructor() { }

  set setSelectData(selectData: IRaidEditData) {
    this.selectData = selectData;
  }

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

  get getSelectData() {
    return this.selectData;
  }

  get getOriginData() {
    return this.originData;
  }

  private static instance: RaidEditModel | null;

  private saveState!: boolean;
  private selectData!: IRaidEditData;
  private originData!: IRaidEditData;

  // smart错误状态
  private smartState!: boolean;
  private jbodShow: boolean | undefined;

  public static getInstance(): RaidEditModel {
    if (!RaidEditModel.instance) {
      RaidEditModel.instance = new RaidEditModel();
    }
    return RaidEditModel.instance;
  }

  public static initRaidEdit(
    jBODState: boolean,
    copyBackState: boolean,
    smarterCopyBackState: boolean,
    workMode: IOptions | null,
    noBBUWriteState?: boolean | null,
    readCachePercent?: number | null,
    bootDevice1?: IOptions,
    bootDevice2?: IOptions,
    writeCacheType?: IOptions,
    writeCachePolicy?: IOptions | null,
  ): RaidEditModel | null {
    RaidEditModel.getInstance().setSelectData = {
      jBODState,
      copyBackState,
      smarterCopyBackState,
      mode: workMode,
      noBatteryWriteCacheEnabled: noBBUWriteState,
      readCachePercent,
      bootDevice1,
      bootDevice2,
      writeCacheType,
      writeCachePolicy,
    };

    RaidEditModel.getInstance().setOriginData = JSON.parse(JSON.stringify(RaidEditModel.getInstance().getSelectData));
    RaidEditModel.getInstance().judgJBODShow();
    RaidEditModel.getInstance().checkSave();
    return this.instance;
  }

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

  public setJBODState(jBODState: boolean) {
    this.selectData.jBODState = jBODState;
    this.checkSave();
  }

  public setCopyBackState(copyBackState: boolean) {
    this.selectData.copyBackState = copyBackState;
    this.smartState = !copyBackState;
    this.checkSave();
  }

  public setSmarter(smarterCopyBackState: boolean) {
    this.selectData.smarterCopyBackState = smarterCopyBackState;
    this.checkSave();
  }

  public setWorkModel(workMode: IOptions): void {
    this.selectData.mode = workMode;
    if (this.selectData.mode.id === Store.JBOD) {
      this.setJBODState(this.originData.jBODState);
    }
    this.judgJBODShow();
    this.checkSave();
  }
  
  public setBootDevice(bootDevice: IOptions, bootNum: number): void {
    if (bootNum === 1) {
      this.selectData.bootDevice1 = bootDevice;
    } else {
      this.selectData.bootDevice2 = bootDevice;
    }
    this.checkSave();
  }
  
  public setWriteCacheType(writeCacheType: IOptions): void {
    this.selectData.writeCacheType = writeCacheType;
    this.checkSave();
  }
  
  public setWriteCachePolicy(writeCachePolicy: IOptions): void {
    this.selectData.writeCachePolicy = writeCachePolicy;
    this.checkSave();
  }

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

  get getSmartState(): boolean {
    return this.smartState;
  }

  public checkSave(uncheck: boolean = false): void {
    if (uncheck) {
      this.saveState = uncheck;
      return;
    }
    if (JSON.stringify(this.originData) === JSON.stringify(this.selectData)) {
      this.saveState = true;
    } else {
      this.saveState = false;
    }
  }
  
  public setReadCachePercent(readCachePercent: number): void {
    if (readCachePercent >= 0 &&
      readCachePercent <= 100 &&
      readCachePercent % 5 === 0
    ) {
      this.selectData.readCachePercent = readCachePercent;
      this.checkSave();
    } else {
      this.checkSave(true);
    }
  }

  private judgJBODShow(): void {
    this.jbodShow = this.selectData.mode ?
      this.selectData.mode.id !== Store.JBOD && this.originData.mode?.id !== Store.JBOD
      : false;
  }

  get getJBODShow() {
    return this.jbodShow;
  }
}
