//  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 { CmdType } from '@/model/base-enum';

export const packed = {

  /**
   * KVM cmdType定义，命名规则如下
   * @param cmdType 消息类型（两个字节）
   * @param bodyData 消息体数据
   * @param bladeId 单板槽位号
   * 消息格式定义：消息体长度(4B)+消息类型(2B)+单板槽位号(1B)+预留块(1B)+消息体
   */
  packageData(cmdType: number, bodyData: number[] = [], bladeId: number = 0xff) {
    const packetedData = new Uint8Array(bodyData.length + 8);
    packetedData[0] = (bodyData.length & 0xff000000) >> 24;
    packetedData[1] = (bodyData.length & 0xff0000) >> 16;
    packetedData[2] = (bodyData.length & 0xff00) >> 8;
    packetedData[3] = bodyData.length & 0xff;
    packetedData[4] = (cmdType & 0xff00) >> 8;
    packetedData[5] = cmdType & 0xff;
    packetedData[6] = bladeId & 0xff;
    packetedData[7] = 0xff;
    bodyData.forEach((item, index) => packetedData[8 + index] = item);
    return packetedData;
  },
  parseData(data: Uint8Array) {
    const result = {
      cmdType: 0,
      bodyData: new Uint8Array(),
      bladeId: 0,
      bodyDataLength: 0
    };
    // 确保获取的消息正确：有消息头(8位)
    if (data.length >= 8) {
      result.bodyDataLength = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
      result.cmdType = (data[4] << 8) + data[5];
      result.bodyData = data.slice(8);
      result.bladeId = data[6];
    }
    return result;
  },
  parseImageBody(data: Uint8Array) {
    const result = {
      imageHight: 0,
      imageWidth: 0,
      imageQuantizationLevel: 0,
      imageFrameType: 0,
      imageLength: 0,
      imageBodyData: new Uint8Array()
    };
    if (data?.length >= 10) {
      result.imageHight = (data[0] << 8) + data[1];
      result.imageWidth = (data[2] << 8) + data[3];
      result.imageQuantizationLevel = data[4];
      result.imageFrameType = data[5];
      result.imageLength = (data[6] << 24) + (data[7] << 16) + (data[8] << 8) + data[9];
      result.imageBodyData = data.slice(10);
    }
    return result;
  },
  // 连接请求
  packConnect(bodyData: number[], bladeId: number) {
    return packed.packageData(CmdType.CONNECT_REQ_C, bodyData, bladeId);
  },
  // 心跳包
  packHeartBeat() {
    return packed.packageData(CmdType.HEARTBEAT_REQ_C);
  },
  // 断开连接请求
  packDisconnect() {
    return packed.packageData(CmdType.DISCONNECT_REQ_C);
  },
  // 设置图像分辨率
  packSetImageResolution(bodyData?: number) {
    return packed.packageData(CmdType.SET_IMAGE_RESOLUTION_REQ_C, (bodyData || bodyData === 0) ? [bodyData & 0xff] : []);
  },
  packGetImageResolution() {
      return packed.packageData(CmdType.GET_IMAGE_RESOLUTION_REQ_C);
  },
  packStartRecord() {
    return packed.packageData(CmdType.SCREEN_RECODING_START_REQ_C);
  },
  packEndRecord() {
    return packed.packageData(CmdType.SCREEN_RECODING_END_REQ_C);
  },
  // 上下电请求
  packPowerCtrl(option: number) {
    const data = new Uint8Array(1);
    data[0] = option & 0xff;
    return packed.packageData(CmdType.POWER_CONTROL_REQ_C, [...data]);
  },
  packGetBootOption() {
    return packed.packageData(CmdType.GET_BOOT_OPTION_REQ_C);
  },
  packGetBootMethod() {
    return packed.packageData(CmdType.GET_BOOT_METHOD_REQ_C);
  },
  packSetBootOption(option: number) {
    const data = new Uint8Array(1);
    data[0] = option & 0xff;
    return packed.packageData(CmdType.SET_BOOT_OPTION_REQ_C, [...data]);
  },
  // 强制I帧请求
  packForceIFrame() {
      return packed.packageData(CmdType.FORCE_I_FRAME_REQ_C);
  },
  packInitKeyBoard() {
    return packed.packageData(CmdType.KEYBOARD_STATUS_REQ_C);
  },
  packGetMouseMode() {
    return packed.packageData(CmdType.GET_MOUSE_MODE_REQ_C);
  },
  packSetMouseMode(option: number = 0) {
    const data = new Uint8Array(1);
    data[0] = option & 0xff;
    return packed.packageData(CmdType.SET_MOUSE_MODE_REQ_C, [...data]);
  },
  packResetUsb() {
    return packed.packageData(CmdType.RESET_USB_REQ_C);
  },
  packKeyBoard(bodyData: number[]) {
    return packed.packageData(CmdType.KEYBOARD_DATA_REQ_C, bodyData);
  },
  packGetCustom(): Uint8Array {
    return packed.packageData(CmdType.CUSTOM_DATA_GET_P);
  },
  packSaveCustom(bodyData: number[]): Uint8Array {
    return packed.packageData(CmdType.CUSTOM_DATA_SAVE_P, bodyData);
  },
  packDelCustom(bodyData: number[]): Uint8Array {
    return packed.packageData(CmdType.CUSTOM_DATA_DEL_P, bodyData);
  },
  packSingleMouse(button: number, x: number, y: number) {
    const data = new Uint8Array(4);
    data[0] = button;
    data[1] = x;
    data[2] = y;
    data[3] = 0;
    return packed.packageData(CmdType.MOUSE_INPUT_REQ_C, [...data]);
  },
  packDualMouse(button: number, x: number, y: number) {
    const data = new Uint8Array(5);
    data[0] = button;
    data[1] = (x & 0xff00) >> 8;
    data[2] = x & 0xff;
    data[3] = (y & 0xff00) >> 8;
    data[4] = y & 0xff;
    return packed.packageData(CmdType.MOUSE_INPUT_REQ_C, [...data]);
  },
  packGetVmmEnable() {
    return packed.packageData(CmdType.VMM_ENABLE_REQ_C);
  },
  packGetVmmPort() {
    return packed.packageData(CmdType.VMM_PORT_REQ_C);
  },
  // 切换激活主机
  packGetActiveHosts(hostId: number) {
    return packed.packageData(CmdType.SCREEN_RECODING_END_REQ_D, [hostId]);
  },
  // 查询当前激活主机
  packGetCurActiveHosts() {
    return packed.packageData(CmdType.SCREEN_RECODING_END_REQ_E);
  },
};