/**
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
 * CANN Open Software License Agreement Version 2.0 (the "License").
 * Please refer to the License for details. You may not use this file except in compliance with the License.
 * 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 FITNESS FOR A PARTICULAR PURPOSE.
 * See LICENSE in the root of the software repository for the full text of the License.
 */

#ifndef CCE_RUNTIME_RT_EXTERNAL_DQS_H
#define CCE_RUNTIME_RT_EXTERNAL_DQS_H

#include "rt_external_base.h"

#if defined(__cplusplus)
extern "C" {
#endif

#ifndef RTS_WEAK
#define RTS_WEAK __attribute__((weak))
#endif

#define RT_DQS_MAX_INPUT_QUEUE_NUM 10U
#define RT_DQS_MAX_OUTPUT_QUEUE_NUM 10U

typedef enum {
    RT_DQS_SCHED_TYPE_NN = 1,  // NN+Q硬化调度
    RT_DQS_SCHED_TYPE_VPC = 2, // VPC/NSC+Q硬化调度
    RT_DQS_SCHED_TYPE_DSS = 3, // DSS+Q硬化调度
} rtDqsSchedType;

typedef enum {
    RT_DQS_FRAME_MAIN_CHANNEL_ALIGN, // 主通路对齐
    RT_DQS_FRAME_ALL_CHANNEL_ALIGN   // 全通路对齐
} rtDqsFrameAlignMode;

typedef enum {
    RT_DQS_DROP_FRAME, // 当前帧不处理,继续等待下一帧,直到所有输入都满足对齐时间阈值
    RT_DQS_USE_DEFAULT_FRAME, // 使用默认帧
    RT_DQS_USE_HISTORY_FRAME  // 使用历史帧
} rtDqsFrameAlignTimeoutMode;

typedef enum {
    RT_DQS_ZERO_COPY_INPUT,  // 输入数据零拷贝
    RT_DQS_ZERO_COPY_OUTPUT, // 输出数据零拷贝
} rtDqsZeroCopyType;

typedef enum { // 零拷贝时,64bit的地址拆分为两个32bit地址,分为高32和低32
    RT_DQS_ZERO_COPY_ADDR_ORDER_LOW32_FIRST = 0,  // 拷贝到目标二进指针地址时,低32bit在前
    RT_DQS_ZERO_COPY_ADDR_ORDER_HIGH32_FIRST = 1, // 拷贝到目标二进指针地址时,高32bit在前
} rtDqsZeroCopyAddrOrderType;

typedef struct {
    uint8_t type;                                         // 硬化调度类型,参考 rtDqsSchedType
    uint8_t reserve;                                      // 预留
    uint8_t inputQueueNum;                                // 输入队列数量
    uint8_t outputQueueNum;                               // 输出队列数量
    uint16_t inputQueueIds[RT_DQS_MAX_INPUT_QUEUE_NUM];   // 输入队列id列表
    uint16_t outputQueueIds[RT_DQS_MAX_OUTPUT_QUEUE_NUM]; // 输出队列id列表
} rtDqsSchedCfg_t;

typedef rtDqsSchedCfg_t rtDqsSchedConfig_t;

// 用于归一接口
typedef struct {
    rtDqsZeroCopyType copyType;
    rtDqsZeroCopyAddrOrderType cpyAddrOrder; // 拷贝到目标二进指针地址时,高32位和低32位的安排顺序。
    uint16_t queueId;                        // 队列id
    uint16_t count;                          // offset和dest数组的数量
    uint32_t rsv;
    uint64_t* dest;                          // 目标地址的指针数组
    uint64_t* offset;                        // offset数组
} rtDqsZeroCopyCfg_t;

typedef struct {
    uint64_t* condition; // 存放condition条件的标志
    void* dst;           // 目的地址
    uint64_t destMax;    // 目的地的最大长度
    void* src;           // 源地址
    uint64_t cnt;        // 拷贝的字节数
} rtDqsConditionCopyCfg_t;

typedef struct {
    uint32_t mbufHandle;  // ADSPC 数据存放mbuf handle,block_id:pool_id
    uint16_t queueId;     // ADSPC 生产者队列id
    uint8_t cqeSize;      // ADSPC CQE大小
    uint8_t cqDepth;      // ADSPC CQ深度
    uint64_t cqeBaseAddr; // ADSPC CQE基地址
    uint64_t cqeCopyAddr; // CQE拷贝目的地址,位于mbuf,由调用者根据mbuf data基地址、block_id、offset偏移计算得到
    uint64_t cqHeadRegAddr; // ADSPC CQ head寄存器地址
    uint64_t cqTailRegAddr; // ADSPC CQ tail寄存器地址
} rtDqsAdspcTaskCfg_t;

typedef enum {
    RT_DQS_TASK_SCHED_CONFIG,
    RT_DQS_TASK_NOTIFY_WAIT,
    RT_DQS_TASK_DEQUEUE,
    RT_DQS_TASK_ZERO_COPY,
    RT_DQS_TASK_CONDITION_COPY,
    RT_DQS_TASK_PREPARE_OUT,
    RT_DQS_TASK_ENQUEUE,
    RT_DQS_TASK_FREE,
    RT_DQS_TASK_FRAME_ALIGN,
    RT_DQS_TASK_SCHED_END,
    RT_DQS_TASK_INTER_CHIP_INIT,
    RT_DQS_TASK_ADSPC,
    RT_DQS_TASK_MAX
} rtDqsTaskType;

typedef struct {
    rtDqsTaskType type;
    uint32_t rsv;
    void* cfg;
} rtDqsTaskCfg_t;

/**
 * @ingroup rts_dqs
 * @brief Launch dqs task in stream
 *
 * @param stm the stream to launch task
 * @param taskCfg the dqs task cfg
 * @return RT_ERROR_NONE for ok
 * @return RT_ERROR_INVALID_VALUE for error input
 */
RTS_API rtError_t rtLaunchDqsTask(const rtStream_t stm, const rtDqsTaskCfg_t* const taskCfg) RTS_WEAK;

#if defined(__cplusplus)
}
#endif
#endif // CCE_RUNTIME_RT_EXTERNAL_DQS_H