/* -------------------------------------------------------------------------
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This file is part of the MindStudio project.
 *
 * MindStudio 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.
 * -------------------------------------------------------------------------
 */

#ifndef MSPTI_COMMON_INJECT_PROFAPI_INJECT_H
#define MSPTI_COMMON_INJECT_PROFAPI_INJECT_H

#include "csrc/common/inject/inject_base.h"
#include "csrc/include/mspti_result.h"

enum ProfilerCallbackType
{
    PROFILE_CTRL_CALLBACK = 0,
    PROFILE_DEVICE_STATE_CALLBACK,
    PROFILE_REPORT_API_CALLBACK,
    PROFILE_REPORT_EVENT_CALLBACK,
    PROFILE_REPORT_COMPACT_CALLBACK,
    PROFILE_REPORT_ADDITIONAL_CALLBACK,
    PROFILE_REPORT_REG_TYPE_INFO_CALLBACK,
    PROFILE_REPORT_GET_HASH_ID_CALLBACK,
    PROFILE_HOST_FREQ_IS_ENABLE_CALLBACK,
    PROFILE_REPORT_API_C_CALLBACK,
    PROFILE_REPORT_EVENT_C_CALLBACK,
    PROFILE_REPORT_REG_TYPE_INFO_C_CALLBACK,
    PROFILE_REPORT_GET_HASH_ID_C_CALLBACK,
    PROFILE_HOST_FREQ_IS_ENABLE_C_CALLBACK,
    PROFILE_REPORT_REG_DATA_FORMAT_CALLBACK,
    PROFILE_REPORT_REG_DATA_FORMAT_C_CALLBACK,
    PROFILE_DEVICE_STATE_C_CALLBACK,
};

#define MSPROF_DATA_HEAD_MAGIC_NUM 0x5a5a
#define MSPROF_EVENT_FLAG 0xFFFFFFFFFFFFFFFFULL
#define PROF_INVALID_MODE_ID 0xFFFFFFFFUL
#define MAX_DEV_NUM 64

#define PROF_ACL_API 0x00000001ULL
#define PROF_TASK_TIME 0x00000800ULL
#define PROF_HCCL_TRACE 0x00000020ULL
#define PROF_RUNTIME_TRACE 0x0000004000000ULL
#define PROF_RUNTIME_API 0x00000100ULL

#define MSPTI_CONFIG_KERNEL (PROF_TASK_TIME | PROF_RUNTIME_TRACE)
#define MSPTI_CONFIG_API (PROF_ACL_API | PROF_TASK_TIME)
#define MSPTI_CONFIG_COMMUNICATION (PROF_ACL_API | PROF_RUNTIME_TRACE | PROF_TASK_TIME | PROF_HCCL_TRACE)
#define MSPTI_CONFIG_RUNTIME_API (PROF_RUNTIME_API)

#define MSPROF_REPORT_RUNTIME_LEVEL 5000U
#define MSPROF_REPORT_NODE_BASE_LEVEL 10000U
#define MSPROF_REPORT_HCCL_NODE_LEVEL 5500U
#define MSPROF_REPORT_ACL_LEVEL 20000U

#define MSPROF_REPORT_HCCL_MASTER_TYPE 10001U
#define MSPROF_REPORT_HCCL_SLAVE_TYPE 10002U
#define MSPROF_STREAM_EXPAND_SPEC_TYPE 804U

const uint32_t MSPROF_REPORT_NODE_HCCL_OP_INFO_TYPE = 10;
const uint32_t MSPROF_REPORT_NODE_LAUNCH_TYPE = 5;

enum AclApiTag
{
    ACL_OP = 1,
    ACL_MODEL = 2,
    ACL_RTS = 3,
    ACL_OTHERS = 4,
    ACL_NN = 5,
    ACL_ASCENDC = 6,
    HOST_HCCL = 7,
    ACL_DVPP = 9,
    ACL_GRAPH = 10,
    ACL_ATB = 11,
};

// for MsprofReportApi
struct MsprofApi
{
    uint16_t magicNumber = MSPROF_DATA_HEAD_MAGIC_NUM;
    uint16_t level;
    uint32_t type;
    uint32_t threadId;
    uint32_t reserve;
    uint64_t beginTime;
    uint64_t endTime;
    uint64_t itemId;
};

// for MsprofReportEvent
struct MsprofEvent
{
    uint16_t magicNumber = MSPROF_DATA_HEAD_MAGIC_NUM;
    uint16_t level;
    uint32_t type;
    uint32_t threadId;
    uint32_t requestId;  // 0xFFFF means single event
    uint64_t timeStamp;
    uint64_t reserve = MSPROF_EVENT_FLAG;
    uint64_t itemId;
};

struct MsprofRuntimeTrack
{
    uint16_t deviceId;
    uint16_t streamId;
    uint32_t taskInfo;
    uint64_t taskType;
    uint64_t kernelName;
};

struct MsprofNodeBasicInfo
{
    uint64_t opName;
    uint32_t taskType;
    uint64_t opType;
    uint32_t blockDim;
    uint32_t opFlag;
    uint8_t opState;
};

struct MsprofAttrInfo
{
    uint64_t opName;
    uint32_t attrType;
    uint64_t hashId;
};

#pragma pack(1)
// for MsprofReportCompactInfo buffer data
struct MsprofHcclOPInfo
{
    uint8_t relay : 1;
    uint8_t retry : 1;
    uint8_t dataType;
    uint64_t algType;  // 通信算子使用的算法,hash的key,其值是以"-"分隔的字符串
    uint64_t count;
    uint64_t groupName;
};
#pragma pack()

#pragma pack(1)
// for MsprofReportCompactInfo buffer data
struct MsprofStreamExpandSpecInfo
{
    uint8_t expandStatus;  // 1: 扩容场景 0: 非扩容场景
    uint8_t reserved1;
    uint16_t reserved2;
};
#pragma pack()

enum RtProfileDataType
{
    RT_PROFILE_TYPE_TASK_BEGIN = 0,
    RT_PROFILE_TYPE_TASK_END = 800,
    RT_PROFILE_TYPE_MEMCPY_INFO = 801,
    RT_PROFILE_TYPE_TASK_TRACK = 802,
    RT_PROFILE_TYPE_API_BEGIN = 1000,
    RT_PROFILE_TYPE_API_END = 2000,
    RT_PROFILE_TYPE_MAX
};

const uint16_t MSPROF_COMPACT_INFO_DATA_LENGTH = 40;
struct MsprofCompactInfo
{
    uint16_t magicNumber = MSPROF_DATA_HEAD_MAGIC_NUM;
    uint16_t level;
    uint32_t type;
    uint32_t threadId;
    uint32_t dataLen;
    uint64_t timeStamp;
    union
    {
        uint8_t info[MSPROF_COMPACT_INFO_DATA_LENGTH];
        MsprofRuntimeTrack runtimeTrack;
        MsprofNodeBasicInfo nodeBasicInfo;
        MsprofAttrInfo nodeAttrInfo;
        MsprofHcclOPInfo hcclopInfo;
        MsprofStreamExpandSpecInfo streamExpandInfo;
    } data;
};

#define PATH_LEN_MAX 1023
#define PARAM_LEN_MAX 4095
struct CommandHandleParams
{
    uint32_t pathLen;
    uint32_t storageLimit;  // MB
    uint32_t profDataLen;
    char path[PATH_LEN_MAX + 1];
    char profData[PARAM_LEN_MAX + 1];
};

struct CommandHandle
{
    uint64_t profSwitch;
    uint64_t profSwitchHi;
    uint32_t devNums;
    uint32_t devIdList[MAX_DEV_NUM];
    uint32_t modelId;
    uint32_t type;
    uint32_t cacheFlag;
    struct CommandHandleParams params;
};

enum CommandHandleType
{
    PROF_COMMANDHANDLE_TYPE_INIT = 0,
    PROF_COMMANDHANDLE_TYPE_START,
    PROF_COMMANDHANDLE_TYPE_STOP,
    PROF_COMMANDHANDLE_TYPE_FINALIZE,
};

struct ProfSetDevPara
{
    uint32_t chipId;
    uint32_t devId;
    bool isOpen;
};

namespace Mspti
{
namespace Inject
{

enum ProfApiErrorCode
{
    PROFAPI_ERROR_NONE = 0,
    PROFAPI_ERROR_MEM_NOT_ENOUGH,
    PROFAPI_ERROR_GET_ENV,
    PROFAPI_ERROR_CONFIG_INVALID,
    PROFAPI_ERROR_ACL_JSON_OFF,
    PROFAPI_ERROR,
    PROFAPI_ERROR_UNINITIALIZE,
};

// 老的数据上报方式,待Lite-Profiling废弃后删除
using ProfReportHandle = int32_t (*)(uint32_t moduleId, uint32_t type, VOID_PTR data, uint32_t len);

// 使能接口
using MsprofCtrlHandle = int32_t (*)(uint32_t type, VOID_PTR data, uint32_t len);
int32_t profSetProfCommand(VOID_PTR command, uint32_t len);
using ProfSetDeviceHandle = int32_t (*)(VOID_PTR deviceState, uint32_t len);
int32_t profRegDeviceStateCallback(ProfSetDeviceHandle handle);

// 新数据结构上报方式
int32_t MsprofRegisterProfileCallback(int32_t callbackType, VOID_PTR callback, uint32_t len);

namespace Detail
{
int32_t MsprofReporterCallbackImpl(uint32_t moduleId, uint32_t type, VOID_PTR data, uint32_t len);
int8_t MsptiHostFreqIsEnableImpl();
uint64_t MsptiGetHashIdImpl(const char* hashInfo, size_t len);
int32_t MsptiApiReporterCallbackImpl(uint32_t agingFlag, const MsprofApi* const data);
int32_t MsptiEventReporterCallbackImpl(uint32_t agingFlag, const MsprofEvent* const event);
int32_t MsptiCompactInfoReporterCallbackImpl(uint32_t agingFlag, CONST_VOID_PTR data, uint32_t length);
int32_t MsptiAddiInfoReporterCallbackImpl(uint32_t agingFlag, CONST_VOID_PTR data, uint32_t length);
int32_t MsptiRegReportTypeInfoImpl(uint16_t level, uint32_t typeId, const char* name, size_t len);
int32_t MsprofDeviceStateImpl(VOID_PTR deviceState, uint32_t len);
}  // namespace Detail
}  // namespace Inject
}  // namespace Mspti

#endif  // MSPTI_COMMON_INJECT_PROFAPI_INJECT_H