/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "common_ffrt.h"
#include "native_log_wrapper.h"

static inline void FfrtExecFunctionWrapper(void *t)
{
    CFunction *f = (CFunction *)t;
    if (f->func) {
        f->func(f->arg);
    }
}

static inline void FfrtDestroyFunctionWrapper(void *t)
{
    CFunction *f = (CFunction *)t;
    if (f->afterFunc) {
        f->afterFunc(f->arg);
    }
}
#define FFRT_STATIC_ASSERT(cond, msg) int x(int static_assertion_##msg[(cond) ? 1 : -1])
static inline ffrt_function_header_t *FfrtCreateFunctionWrapper(const ffrt_function_t func,
                                                                const ffrt_function_t afterFunc, void *arg)
{
    FFRT_STATIC_ASSERT(sizeof(CFunction) <= ffrt_auto_managed_function_storage_size,
                       size_of_function_must_be_less_than_ffrt_auto_managed_function_storage_size);

    CFunction *f = (CFunction *)ffrt_alloc_auto_managed_function_storage_base(ffrt_function_kind_queue);
    f->header.exec = FfrtExecFunctionWrapper;
    f->header.destroy = FfrtDestroyFunctionWrapper;
    f->func = func;
    f->afterFunc = afterFunc;
    f->arg = arg;
    return (ffrt_function_header_t *)f;
}

ffrt_queue_t CreateBankSystem(const char *name, int concurrency, int type)
{
    ffrt_queue_attr_t queueAttr;
    (void)ffrt_queue_attr_init(&queueAttr);
    ffrt_queue_attr_set_max_concurrency(&queueAttr, concurrency);

    // 创建一个并发/串行 队列
    ffrt_queue_t queue;
    if (type == TYPE_CONCURRENT) {
        queue = ffrt_queue_create(ffrt_queue_concurrent, name, &queueAttr);
    } else {
        queue = ffrt_queue_create(ffrt_queue_serial, name, &queueAttr);
    }

    // 队列创建完后需要销毁队列属性
    ffrt_queue_attr_destroy(&queueAttr);
    if (!queue) {
        LOGE("create queue failed");
        return NULL;
    }

    LOGI("create bank system successfully");
    return queue;
}

void DestroyBankSystem(ffrt_queue_t queueHandle)
{
    ffrt_queue_destroy(queueHandle);
    LOGI("destroy bank system successfully");
}

// 封装提交队列任务函数
ffrt_task_handle_t CommitRequest(ffrt_queue_t bank, void (*func)(void *), CRequest request, ffrt_queue_priority_t level,
                                 int delay)
{
    ffrt_task_attr_t taskAttr;
    (void)ffrt_task_attr_init(&taskAttr);
    ffrt_task_attr_set_name(&taskAttr, request.name);
    ffrt_task_attr_set_queue_priority(&taskAttr, level);
    ffrt_task_attr_set_delay(&taskAttr, delay);

    return ffrt_queue_submit_h(bank, FfrtCreateFunctionWrapper(func, NULL, request.arg), &taskAttr);
}

// 封装等待队列任务函数
void WaitForRequest(ffrt_task_handle_t task) { ffrt_queue_wait(task); }