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

export class DriveStaticModel {
  private constructor() {}

  get getFirmwareOptions(): IOptions[] {
    return this.firmwareOptions;
  }

  private static instance: DriveStaticModel;

  public static readonly INDICATOR = {
    indicatorOn: {
      id: 'Blinking',
      label: 'STORE_ENABLED',
      state: true,
      name: 'ISwitch',
    },
    indicatorOff: {
      id: 'Off',
      label: 'STORE_DISABLED',
      state: false,
      name: 'ISwitch',
    },
  };

  // 是否为启动盘
  public static readonly isBootDisk: IStorageRadio[] = [
    {
      label: 'COMMON_YES',
      id: true,
      disable: false,
      name: 'IRadio',
      attrName: 'BootDisk',
    },
    {
      label: 'COMMON_NO',
      id: false,
      disable: false,
      name: 'IRadio',
      attrName: 'BootDisk',
    },
  ];

  // 巡检开关状态STORE_PATROL_SWITCH
  public static readonly patrolSwitchStatus = [
    {
      label: 'FDM_ENABLED',
      id: 'Patrolling',
      disable: false,
      name: 'IRadio',
      attrName: 'PatrolSwitch',
    },
    {
      label: 'FDM_DISABLED',
      id: 'DoneOrNotPatrolled',
      disable: false,
      name: 'IRadio',
      attrName: 'PatrolSwitch',
    },
  ];

  // 启动盘设置
  public static readonly pmcBootPriority: IOptions[] = [
    {
      id: 'Primary',
      label: 'Primary',
      name: 'IOptions',
    },
    {
      id: 'Secondary',
      label: 'Secondary',
      name: 'IOptions',
    },
    {
      id: 'All',
      label: 'All',
      name: 'IOptions',
    },
    {
      id: 'None',
      label: 'None',
      name: 'IOptions',
    },
  ];

  public static readonly HOTSPARERADIOS = {
    none: {
      id: 'None',
      label: 'STORE_NONE',
      name: 'IRadio',
      disable: false,
    },
    global: {
      id: 'Global',
      label: 'STORE_GLOBAL',
      name: 'IRadio',
      disable: false,
    },
    dedicated: {
      id: 'Dedicated',
      label: 'STORE_DEDICATED',
      name: 'IRadio',
      disable: false,
    },
    autoReplace: {
      id: 'Auto Replace',
      label: 'STORE_AUTOREPLACE',
      name: 'IRadio',
      disable: false,
    },
  };

  // 固件状态
  public static readonly FIRMWARESTATUS = {
    online: {
      id: 'Online',
      label: 'ONLINE',
      name: 'IOptions',
    },
    offline: {
      id: 'Offline',
      label: 'OFFLINE',
      name: 'IOptions',
    },
    unconfiguredGood: {
      id: 'UnconfiguredGood',
      label: 'UNCONFIGURED GOOD',
      name: 'IOptions',
    },
    unconfiguredBad: {
      id: 'UnconfiguredBad',
      label: 'UNCONFIGURED BAD',
      name: 'IOptions',
    },
    jbod: {
      id: 'JBOD',
      label: 'JBOD',
      name: 'IOptions',
    },
    hotSpareDrive: {
      id: 'HotSpareDrive',
      label: 'HOT SPARE',
      name: 'IOptions',
    },
    failed: {
      id: 'Failed',
      label: 'FAILED',
      name: 'IOptions',
    },
    rebuilding: {
      id: 'Rebuilding',
      label: 'REBUILD',
      name: 'IOptions',
    },
    gettingCopied: {
      id: 'GettingCopied',
      label: 'COPYBACK',
      name: 'IOptions',
    },
    unconfiguredShielded: {
      id: 'UnconfiguredShielded',
      label: 'UNCONFIGURED (Shielded)',
      name: 'IOptions',
    },
    hotSpareShielded: {
      id: 'HotSpareShielded',
      label: 'HOT SPARE (Shielded)',
      name: 'IOptions',
    },
    configuredShielded: {
      id: 'ConfiguredShielded',
      label: 'CONFIGURED (Shielded)',
      name: 'IOptions',
    },
    foreign: {
      id: 'Foreign',
      label: 'FOREIGN',
      name: 'IOptions',
    },
    active: {
      id: 'Active',
      label: 'Active',
      name: 'IOptions',
    },
    standby: {
      id: 'Standby',
      label: 'Stand-by',
      name: 'IOptions',
    },
    sleep: {
      id: 'Sleep',
      label: 'Sleep',
      name: 'IOptions',
    },
    dstInProgress: {
      id: 'DSTInProgress',
      label: 'DST executing in background',
      name: 'IOptions',
    },
    smartOfflineDataCollection: {
      id: 'SMARTOfflineDataCollection',
      label: 'SMART Off-line Data Collection executing in background',
      name: 'IOptions',
    },
    sctCommand: {
      id: 'SCTCommand',
      label: 'SCT command executing in background',
      name: 'IOptions',
    },
    raw: {
      id: 'Raw',
      label: 'Raw',
      name: 'IOptions',
    },
    ready: {
      id: 'Ready',
      label: 'Ready',
      name: 'IOptions',
    },
  };

  private firmwareOptions!: IOptions[];

  public static getInstance(): DriveStaticModel {
    if (!DriveStaticModel.instance) {
      DriveStaticModel.instance = new DriveStaticModel();
    }
    return DriveStaticModel.instance;
  }
  
  public static getIsBootDisk(key: boolean): IStorageRadio | null {
    const result = DriveStaticModel.isBootDisk.filter(opt => opt.id === key);
    return result.length > 0 ? result[0] : null;
  }

  public static getPatrol(key: string | null): IStorageRadio | null {
    const result = DriveStaticModel.patrolSwitchStatus.filter(opt => opt.id === key);
    return result.length > 0 ? result[0] : null;
  }

  /**
   * 根据接口返回值生成固件状态下拉选项
   * @param key 接口返回值
   * @param jbodState JBOD是否开启
   */
  public optionsFactory(
    key: string,
    jbodState: boolean,
    workMode: IOptions | null,
    isEPD: boolean,
    epdSupported: boolean,
  ): IOptions[] {
    if (Store[key]) {
      return firmwareOptionsFactory[key](jbodState, workMode, isEPD, epdSupported);
    } else {
      let firmwareOptions: IOptions[] = [];
      for (const attr in DriveStaticModel.FIRMWARESTATUS) {
        if (
          Object.prototype.hasOwnProperty.call(DriveStaticModel.FIRMWARESTATUS, attr) &&
          DriveStaticModel.FIRMWARESTATUS[attr].id === key
        ) {
          firmwareOptions.push(DriveStaticModel.FIRMWARESTATUS[attr]);
          break;
        }
      }
      return firmwareOptions;
    }
  }

  /**
   * 获取选中的固件状态
   * @param key 接口返回值
   */
  public getFirmwareStatus(key: string): IOptions | null {
    for (const attr in DriveStaticModel.FIRMWARESTATUS) {
      if (
        Object.prototype.hasOwnProperty.call(DriveStaticModel.FIRMWARESTATUS, attr) &&
        DriveStaticModel.FIRMWARESTATUS[attr].id === key
      ) {
        return DriveStaticModel.FIRMWARESTATUS[attr];
      }
    }
    return null;
  }

  /**
   * 获取选中的定位状态
   * @param key 接口返回值
   */
  public getIndicator(key: string): ISwitch | null {
    for (const attr in DriveStaticModel.INDICATOR) {
      if (
        Object.prototype.hasOwnProperty.call(DriveStaticModel.INDICATOR, attr) &&
        DriveStaticModel.INDICATOR[attr].id === key
      ) {
        return DriveStaticModel.INDICATOR[attr];
      }
    }
    return null;
  }

  public getHotspareType(key: string): IRadio | null {
    for (const attr in DriveStaticModel.HOTSPARERADIOS) {
      if (
        Object.prototype.hasOwnProperty.call(DriveStaticModel.HOTSPARERADIOS, attr) &&
        DriveStaticModel.HOTSPARERADIOS[attr].id === key
      ) {
        return DriveStaticModel.HOTSPARERADIOS[attr];
      }
    }
    return null;
  }
  
  public getBootPriority(key: string): IOptions {
    return DriveStaticModel.pmcBootPriority.filter(item => {
      return item.id === key;
    })[0] || null;
  }
}

const firmwareOptionsFactory: object = {
  Online(jbodState: boolean, workMode: IOptions | null, isEPD: boolean, epdSupported: boolean) {
    let firmwareOptions: IOptions[] = [];
    // EDP盘，可以从online设置成UG，否则只能从onlie设置成offline
    if (epdSupported && isEPD) {
      firmwareOptions = [
        DriveStaticModel.FIRMWARESTATUS.unconfiguredGood,
        DriveStaticModel.FIRMWARESTATUS.online,
      ];
    } else {
      firmwareOptions = [
        DriveStaticModel.FIRMWARESTATUS.online,
        DriveStaticModel.FIRMWARESTATUS.offline,
      ];
    }
    return firmwareOptions;
  },
  Offline() {
    let firmwareOptions: IOptions[] = [];
    firmwareOptions = [
      DriveStaticModel.FIRMWARESTATUS.online,
      DriveStaticModel.FIRMWARESTATUS.offline,
    ];
    return firmwareOptions;
  },
  UnconfiguredGood(
    jbodState: boolean,
    workMode: IOptions | null,
    isEPD: boolean,
    epdSupported: boolean,
  ) {
    let firmwareOptions: IOptions[] = [];
    firmwareOptions = [DriveStaticModel.FIRMWARESTATUS.unconfiguredGood];
    if (epdSupported) {
      firmwareOptions.push(DriveStaticModel.FIRMWARESTATUS.online);
    } else if (jbodState) {
      firmwareOptions.push(DriveStaticModel.FIRMWARESTATUS.jbod);
    }
    return firmwareOptions;
  },
  JBOD() {
    let firmwareOptions: IOptions[] = [];
    firmwareOptions = [
      DriveStaticModel.FIRMWARESTATUS.unconfiguredGood,
      DriveStaticModel.FIRMWARESTATUS.jbod,
    ];
    return firmwareOptions;
  },
  UnconfiguredBad() {
    let firmwareOptions: IOptions[] = [];
    firmwareOptions = [
      DriveStaticModel.FIRMWARESTATUS.unconfiguredGood,
      DriveStaticModel.FIRMWARESTATUS.unconfiguredBad,
    ];
    return firmwareOptions;
  },
};
