//  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 { reqPath } from '@/api/reqPath';
import $http from '@/utils/http-service';

const BMA = 'BMA';
const serverMethods = [
  'getIbmaData',
  'getIbmaLogData',
  'updateIbmaLogData',
  'usbStickControl',
  'keepAlive',
  'generateStartupFile',
  'refreshActivationState',
  'getBasicData',
  'patchBasicData',
  'getTimerData',
  'patchTimerData',
] as Array<keyof IbmaService>;

function bindMethods<T>(instance: T, methods: Array<keyof T>): void {
  methods.forEach(method => {
    const fn = instance[method];
    if (typeof fn === 'function') {
      (instance[method] as any) = fn.bind(instance);
    }
  });
}

class IbmaService {
  private static instance: IbmaService | null = null;
  
  constructor(private smsName: string = BMA) {}

  static getInstance(smsName: string): IbmaService {
    if (!IbmaService.instance) {
      IbmaService.instance = new IbmaService(smsName);
      bindMethods(IbmaService.instance, serverMethods);
    }
    return IbmaService.instance;
  }

  // 获取Ibma数据
  getIbmaData(): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .get(reqPath.manager.ibma.getIbmaData.replace(BMA, this.smsName))
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  // 获取IbmaLog数据
  getIbmaLogData(): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .get(reqPath.manager.ibma.getIbmaLogData.replace(BMA, this.smsName))
        .then((res: any) => {
          resolve(res);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  // 提交日志弹窗数据
  updateIbmaLogData(params: any, etag: string): Promise<any> {
    const config = { headers: { 'If-Match': etag } };
    return new Promise((resolve, reject) => {
      $http
        .patch(reqPath.manager.ibma.getIbmaLogData.replace(BMA, this.smsName), params, config)
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  // 安装IBMC
  usbStickControl(params: any): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .post(reqPath.manager.ibma.usbStickControl.replace(BMA, this.smsName), params)
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  // 安装IBMC
  keepAlive(params: any): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .post(reqPath.manager.ibma.keepAlive, params)
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  // 安装IBMC
  generateStartupFile(params: any, httpOptions: any): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .post(reqPath.manager.ibma.generateStartupFile, params, httpOptions)
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  refreshActivationState(): Promise<any> {
    return $http.post(reqPath.manager.ibma.keepAlive, { Mode: 'Activate' }, { keepAlive: true });
  }

  getBasicData(): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .get(`/UI/Rest/BMCSettings/${this.smsName}/Base`)
        .then((res: any) => {
          resolve(res);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  patchBasicData(params: any, etag: string): Promise<any> {
    const config = { headers: { 'If-Match': etag } };
    const param = {
      Attributes: params,
    };
    return new Promise((resolve, reject) => {
      $http
        .patch(`/UI/Rest/BMCSettings/${this.smsName}/Base`, param, config)
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  getTimerData(): Promise<any> {
    return new Promise((resolve, reject) => {
      $http
        .get(`/UI/Rest/BMCSettings/${this.smsName}/Monitor`)
        .then((res: any) => {
          resolve(res);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }

  patchTimerData(Members: any, etag: string): any {
    const config = { headers: { 'If-Match': etag } };
    const params = {
      Members,
    };
    return new Promise((resolve, reject) => {
      $http
        .patch(`/UI/Rest/BMCSettings/${this.smsName}/Monitor`, params, config)
        .then((res: any) => {
          resolve(res.data);
        })
        .catch((err: any) => {
          reject(err);
        });
    });
  }
}

export default IbmaService.getInstance;