/*
 * Copyright (C) 2019-2020 Intel Corporation.
 *
 * 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.
 */

#define LOG_TAG "PGCommon"

#include "PGCommon.h"

#include <stdint.h>
#include <math.h>
#include <utility>
#include "iutils/Utils.h"
#include "iutils/CameraLog.h"
#include "iutils/CameraDump.h"

namespace icamera {

#define IS_VALID_TERMINAL(terminal) (terminal >=0 && terminal < mTerminalCount)

int PGCommon::getFrameSize(int format, int width, int height,
                           bool needAlignedHeight, bool needExtraSize, bool needCompression)
{
    int size = 0;
    int cssFormat = PGUtils::getCssFmt(format);
    int stride = PGUtils::getCssStride(format, width);
    switch (cssFormat) {
    case IA_CSS_DATA_FORMAT_BAYER_LINE_INTERLEAVED:  // CSL6
        if (needAlignedHeight) {
            height = ALIGN_64(height);
        }
        size = stride * height * 3 / 2;
        break;
    default:
        break;
    }

    if (!size) {
        size = CameraUtils::getFrameSize(format, width, height,
                                         needAlignedHeight, needExtraSize, needCompression);
    }
    return size;
}

PGCommon::PGCommon(int pgId, const std::string& pgName, ia_uid terminalBaseUid):
    mCtx(nullptr),
    mManifestBuffer(nullptr),
    mPGParamsBuffer(nullptr),
    mPGParamAdapt(nullptr),
    mPGId(pgId),
    mName(pgName),
    mTerminalBaseUid(terminalBaseUid),
    mStreamId(-1),
    mPGCount(0),
    mPlatform(IA_P2P_PLATFORM_BXT_B0),
    mProgramCount(0),
    mTerminalCount(0),
    mManifestSize(0),
    mKernelBitmap(ia_css_kernel_bitmap_clear()),
    mRoutingBitmap(nullptr),
    mFragmentCount(1),
    mPGBuffer(nullptr),
    mProcessGroup(nullptr),
    mCmdExtBuffer(nullptr),
    mPPG(false),
    mPPGStarted(false),
    mPPGBuffer(nullptr),
    mPPGProcessGroup(nullptr),
    mToken(0),
    mEvent(nullptr),
    mTerminalBuffers(nullptr),
    mInputMainTerminal(-1),
    mOutputMainTerminal(-1),
    mShareReferPool(nullptr)
{
    mTnrTerminalPair.inId = -1;
    mTnrTerminalPair.outId = -1;
    CLEAR(mParamPayload);
    CLEAR(mShareReferIds);
}

PGCommon::~PGCommon()
{
}

int PGCommon::init()
{
    mDisableDataTermials.clear();
    mPGParamAdapt = std::unique_ptr<IntelPGParam>(new IntelPGParam(mPGId));

    mCtx = new CIPR::Context();
    int ret = getCapability();
    if (ret != OK) return ret;

    // create mManifestBuffer
    ret = getManifest(mPGId);
    if (ret != OK) return ret;

    mTerminalBuffers = (CIPR::Buffer**)CIPR::callocMemory(mTerminalCount, sizeof(CIPR::Buffer*));
    CheckError(!mTerminalBuffers, NO_MEMORY, "Allocate terminal buffers fail");
    memset(mTerminalBuffers, 0, (mTerminalCount * sizeof(CIPR::Buffer*)));

    mFrameFormatType = std::unique_ptr<ia_css_frame_format_type[]>(new ia_css_frame_format_type[mTerminalCount]);
    for (int i = 0; i < mTerminalCount; i++) {
        mFrameFormatType[i] = IA_CSS_N_FRAME_FORMAT_TYPES;
    }

    mPgTerminals = std::unique_ptr<uint8_t[]>(new uint8_t[mTerminalCount]);
    for (int i = 0; i < mTerminalCount; i++) {
        mPgTerminals[i] = IPU_MAX_TERMINAL_COUNT;
    }

    std::vector<TerminalPair> tnrTerminalPairs;
    if (PGUtils::getTerminalPairs(mPGId, PGUtils::TERMINAL_PAIR_TNR, &tnrTerminalPairs)) {
        mTnrTerminalPair = tnrTerminalPairs[0];
    }
    PGUtils::getTerminalPairs(mPGId, PGUtils::TERMINAL_PAIR_DVS, &mDvsTerminalPairs);
    PGUtils::getTerminalPairs(mPGId, PGUtils::TERMINAL_PAIR_TNR_SIM, &mTnrSimTerminalPairs);

    return ret;
}

void PGCommon::deInit()
{
    if (mPPGStarted) {
        stopPPG();
        mPPGStarted = false;
    }

    destoryCommands();

    while (!mTnrDataBuffers.empty()) {
        uint8_t* ptr = mTnrDataBuffers.back();
        mTnrDataBuffers.pop_back();
        free(ptr);
    }

    mDvsTerminalPairs.clear();
    mTnrSimTerminalPairs.clear();

    mDisableDataTermials.clear();
    if (mTerminalBuffers) {
        CIPR::freeMemory(mTerminalBuffers);
    }

    delete mManifestBuffer;
    delete mPGParamsBuffer;
    delete mPGBuffer;
    if (mPPGBuffer) {
        delete mPPGBuffer;
    }
    for (auto& item : mBuffers) {
        delete item.ciprBuf;
    }

    delete mCtx;

    mPGParamAdapt->deinit();
    mRoutingBitmap.reset();
}

void PGCommon::setInputInfo(const TerminalFrameInfoMap& inputInfos)
{
    mInputMainTerminal = -1;
    int maxFrameSize = 0;
    for (const auto& item : inputInfos) {
        int terminal = item.first - mTerminalBaseUid;
        CheckError(!IS_VALID_TERMINAL(terminal), VOID_VALUE, "error input terminal %d", item.first);

        FrameInfo frameInfo;
        frameInfo.mWidth = item.second.mWidth;
        frameInfo.mHeight = item.second.mHeight;
        frameInfo.mFormat = item.second.mFormat;
        frameInfo.mBpp = CameraUtils::getBpp(frameInfo.mFormat);
        frameInfo.mStride = CameraUtils::getStride(frameInfo.mFormat, frameInfo.mWidth);
        mTerminalFrameInfos[terminal] = frameInfo;
        int size = frameInfo.mWidth * frameInfo.mHeight;
        if (maxFrameSize < size) {
            maxFrameSize = size;
            mInputMainTerminal = terminal;
        }
    }

    // Create frame info for tnr terminals (i.e. data terminals)
    FrameInfo config = mTerminalFrameInfos[mInputMainTerminal];
    if (config.mHeight % 32) {
        LOG1("%s: height %d not multiple of 32, rounding up!", __func__, config.mHeight);
        config.mHeight = ((config.mHeight / 32) + 1) * 32;
    }

    for (int i = PAIR_BUFFER_IN_INDEX; i <= PAIR_BUFFER_OUT_INDEX; i++) {
        int tnrId = (i == PAIR_BUFFER_IN_INDEX) ? mTnrTerminalPair.inId : mTnrTerminalPair.outId;
        if (tnrId < 0) continue;

        mFrameFormatType[tnrId] = IA_CSS_DATA_FORMAT_NV12; // for IPU6
        mTerminalFrameInfos[tnrId] = config;
    }

    LOG1("%s:%d use input terminal %d as main", __func__, mPGId, mInputMainTerminal);
}

void PGCommon::setOutputInfo(const TerminalFrameInfoMap& outputInfos)
{
    mOutputMainTerminal = -1;
    int maxFrameSize = 0;
    for (const auto& item : outputInfos) {
        int terminal = item.first - mTerminalBaseUid;
        CheckError(!IS_VALID_TERMINAL(terminal), VOID_VALUE, "error output terminal %d", item.first);

        FrameInfo frameInfo;
        frameInfo.mWidth = item.second.mWidth;
        frameInfo.mHeight = item.second.mHeight;
        frameInfo.mFormat = item.second.mFormat;
        frameInfo.mBpp = CameraUtils::getBpp(frameInfo.mFormat);
        frameInfo.mStride = CameraUtils::getStride(frameInfo.mFormat, frameInfo.mWidth);
        mTerminalFrameInfos[terminal] = frameInfo;
        int size = frameInfo.mWidth * frameInfo.mHeight;
        if (maxFrameSize < size) {
            maxFrameSize = size;
            mOutputMainTerminal = terminal;
        }
    }
}

void PGCommon::setDisabledTerminals(const std::vector<ia_uid>& disabledTerminals)
{
    for (auto const terminalUid : disabledTerminals) {
        int terminal = terminalUid - mTerminalBaseUid;
        CheckError(!IS_VALID_TERMINAL(terminal), VOID_VALUE, "error disabled terminal %d", terminalUid);
        mDisableDataTermials.push_back(terminal);
    }
}

void PGCommon::setRoutingBitmap(const void* rbm, uint32_t bytes)
{
    if (!rbm || !bytes) {
        return;
    }
    const unsigned char* rbmData = (const unsigned char*)rbm;

    if (mRoutingBitmap.get() == nullptr) {
        mRoutingBitmap = std::unique_ptr<ia_css_rbm_t>(new ia_css_rbm_t);
    }

    ia_css_rbm_t* rbmPtr = mRoutingBitmap.get();
    *rbmPtr = ia_css_rbm_clear();
    for (uint32_t bit = 0; bit < bytes * 8; bit++) {
        if (rbmData[bit / 8] & (1 << (bit %8))) {
            *rbmPtr = ia_css_rbm_set(*rbmPtr, bit);
        }
    }
}

int PGCommon::prepare(IspParamAdaptor* adaptor, int streamId)
{
    mStreamId = streamId;
    // Set the data terminal frame format
    int ret = configTerminalFormat();
    CheckError((ret != OK), ret, "%s, call configTerminal fail", __func__);

    // Init and config p2p handle
    ret = initParamAdapt();
    CheckError((ret != OK), ret, "%s, init p2p fail", __func__);

    // Query and save the requirement for each terminal, get the final kernel bitmap
    ret = mPGParamAdapt->prepare(adaptor->getIpuParameter(-1, streamId), mRoutingBitmap.get(), &mKernelBitmap);
    CheckError((ret != OK), ret, "%s, prepare p2p fail", __func__);

    // Init PG parameters
    ret = handlePGParams(mFrameFormatType.get());
    CheckError((ret != OK), ret, "%s, call handlePGParams fail", __func__);

    ret = setKernelBitMap();
    CheckError((ret != OK), ret, "%s, call setKernelBitMap fail", __func__);

    ret = setTerminalParams(mFrameFormatType.get());
    CheckError((ret != OK), ret, "%s, call setTerminalParams fail", __func__);

   // Create process group
    mProcessGroup = createPG(&mPGBuffer);
    CheckError(!mProcessGroup, UNKNOWN_ERROR, "%s, create pg fail", __func__);
    uint8_t pgTerminalCount = ia_css_process_group_get_terminal_count(mProcessGroup);
    for (uint8_t termNum = 0 ; termNum < pgTerminalCount; termNum++) {
        ia_css_terminal_t* terminal = ia_css_process_group_get_terminal(mProcessGroup, termNum);
        CheckError(!terminal, UNKNOWN_ERROR, "failed to get terminal");
        uint16_t termIdx = ia_css_terminal_get_terminal_manifest_index(terminal);
        CheckError((termIdx >= IPU_MAX_TERMINAL_COUNT), UNKNOWN_ERROR, "wrong term index for terminal num %d", termNum);
        mPgTerminals[termIdx] = termNum;
    }

    mPGParamAdapt->setPGAndPrepareProgram(mProcessGroup);
    ret = configureFragmentDesc();
    CheckError((ret != OK), ret, "%s, call configureFragmentDesc fail", __func__);

    ret = allocateTnrDataBuffers();
    CheckError((ret != OK), ret, "%s, call allocateTnrDataBuffers fail", __func__);
    ret = preparePayloadBuffers();
    CheckError((ret != OK), NO_MEMORY, "%s, preparePayloadBuffers fails", __func__);

    return OK;
}

ia_css_process_group_t* PGCommon::createPG(CIPR::Buffer** pgBuffer)
{
    CheckError(*pgBuffer, nullptr, "pg has already created");

   // Create process group
    ia_css_program_group_param_t* pgParamsBuf =
        (ia_css_program_group_param_t*)getCiprBufferPtr(mPGParamsBuffer);
    ia_css_program_group_manifest_t* manifestBuf =
        (ia_css_program_group_manifest_t*)getCiprBufferPtr(mManifestBuffer);

    size_t pgSize = ia_css_sizeof_process_group(manifestBuf, pgParamsBuf);
    LOG1("%s process group size is %zu", __func__, pgSize);

    void* pgMemory = mPGParamAdapt->allocatePGBuffer(pgSize);
    CheckError(!pgMemory, nullptr, "allocate PG error");
    *pgBuffer = createUserPtrCiprBuffer(pgSize, pgMemory);
    CheckError(!*pgBuffer, nullptr, "%s, call createUserPtrCiprBuffer fail", __func__);

    ia_css_process_group_t* pg = ia_css_process_group_create(getCiprBufferPtr(*pgBuffer),
                   (ia_css_program_group_manifest_t*)getCiprBufferPtr(mManifestBuffer),
                   (ia_css_program_group_param_t*)getCiprBufferPtr(mPGParamsBuffer));
    CheckError(!pg, nullptr, "Create process group failed.");

    if (mPPG) {
        ia_css_process_group_set_num_queues(pg, 1);
    }

    if (mRoutingBitmap.get()) {
        ia_css_process_group_set_routing_bitmap(pg, *mRoutingBitmap.get());
    }
    return pg;
}

int PGCommon::createCommands()
{
    int bufCount = ia_css_process_group_get_terminal_count(mProcessGroup);
    int ret = createCommand(mPGBuffer, &mCmd, &mCmdExtBuffer, bufCount);
    CheckError(ret, NO_MEMORY, "create cmd fail!");
    if (mPPG) {
        ret = createCommand(mPPGBuffer, &mPPGCmd[PPG_CMD_TYPE_START], &mPPGCmdExtBuffer[PPG_CMD_TYPE_START], bufCount);
        CheckError(ret, NO_MEMORY, "create ppg start buffer %d fail");
        ret = createCommand(mPPGBuffer, &mPPGCmd[PPG_CMD_TYPE_STOP], &mPPGCmdExtBuffer[PPG_CMD_TYPE_STOP], 0);
        CheckError(ret, NO_MEMORY, "create ppg stop %d fail");
    }

    CIPR::PSysEventConfig eventCfg = {};
    eventCfg.timeout = kEventTimeout;
    mEvent = new CIPR::Event(eventCfg);

    return OK;
}

int PGCommon::createCommand(CIPR::Buffer* pg, CIPR::Command** cmd, CIPR::Buffer** extBuffer, int bufCount)
{
    CIPR::PSysCommandConfig cmdCfg;
    CIPR::ProcessGroupCommand *pgCommand;
    CIPR::Result ret;

    // Create command with basic setting
    cmdCfg.buffers.resize(bufCount);
    std::fill(cmdCfg.buffers.begin(), cmdCfg.buffers.end(), nullptr);

    *cmd = new CIPR::Command(cmdCfg);
    ret = (*cmd)->getConfig(&cmdCfg);
    CheckError(ret != CIPR::Result::OK, UNKNOWN_ERROR, "%s, call get_command_config fail", __func__);

    // Create ext buffer
    *extBuffer = new CIPR::Buffer(sizeof(CIPR::ProcessGroupCommand),
                                  CIPR::MemoryFlag::AllocateCpuPtr
                                  | CIPR::MemoryFlag::PSysAPI,
                                  nullptr);

    ret = (*extBuffer)->attatchDevice(mCtx);
    CheckError(ret != CIPR::Result::OK, NO_MEMORY, "unable to access extBuffer");

    void* p = nullptr;
    ret = (*extBuffer)->getMemoryCpuPtr(&p);
    CheckError(ret != CIPR::Result::OK, NO_MEMORY, "unable to access extBuffer memory");
    pgCommand = reinterpret_cast<CIPR::ProcessGroupCommand*>(p);
    CheckError(!pgCommand, NO_MEMORY, "unable to access memory.cpu_ptr");

    pgCommand->header.size = sizeof(CIPR::ProcessGroupCommand);
    pgCommand->header.offset = sizeof(pgCommand->header);
    pgCommand->header.version = psys_command_ext_ppg_1; // for ipu6
    if (pgCommand->header.version == psys_command_ext_ppg_1) {
        CIPR::memoryCopy(pgCommand->dynamicKernelBitmap, sizeof(ia_css_kernel_bitmap_t),
                        &mKernelBitmap, sizeof(ia_css_kernel_bitmap_t));
    }

    // Update setting and set back to command
    cmdCfg.id = mPGId;
    cmdCfg.priority = 1;
    cmdCfg.pgParamsBuf = mPPG ? nullptr : mPGParamsBuffer;
    cmdCfg.pgManifestBuf = mManifestBuffer;
    cmdCfg.pg = pg;
    cmdCfg.extBuf = *extBuffer;
    ret = (*cmd)->setConfig(cmdCfg);
    CheckError(ret != CIPR::Result::OK, UNKNOWN_ERROR, "%s, call set_command_config fail", __func__);

    return OK;
}

void PGCommon::destoryCommands()
{
    delete mCmd;
    delete mCmdExtBuffer;

    for (int i = 0; i < PPG_CMD_TYPE_COUNT; i++) {
        delete mPPGCmd[i];
        delete mPPGCmdExtBuffer[i];
    }

    if (mEvent) {
        delete mEvent;
    }
}

int PGCommon::configTerminalFormat()
{
    for (int i = 0; i < mTerminalCount; i++) {
        if (mTerminalFrameInfos.find(i) != mTerminalFrameInfos.end()) {
            mFrameFormatType[i] = PGUtils::getCssFmt(mTerminalFrameInfos[i].mFormat);
        }
    }
    return OK;
}

int PGCommon::initParamAdapt()
{
    mFragmentCount = calcFragmentCount();

    ia_css_program_group_manifest_t* manifestBuf =
        (ia_css_program_group_manifest_t*)getCiprBufferPtr(mManifestBuffer);

    PgConfiguration config;
    config.pgManifest = manifestBuf;
    config.pgManifestSize = getCiprBufferSize(mManifestBuffer);
    config.disableDataTermials = mDisableDataTermials;
    config.fragmentCount = mFragmentCount;

    FrameInfo* pgInFrame = nullptr;
    FrameInfo* pgOutFrame = nullptr;
    if (mInputMainTerminal >= 0) {
        pgInFrame = &mTerminalFrameInfos[mInputMainTerminal];
    }
    if (mOutputMainTerminal >= 0) {
        pgOutFrame = &mTerminalFrameInfos[mOutputMainTerminal];
    }
    if (pgInFrame) {
        config.inputMainFrame.width = pgInFrame->mWidth;
        config.inputMainFrame.height = pgInFrame->mHeight;
        config.inputMainFrame.bpe = pgInFrame->mBpp; //TODO: use bpe
    }

    if (pgOutFrame) {
        config.outputMainFrame.width = pgOutFrame->mWidth;
        config.outputMainFrame.height = pgOutFrame->mHeight;
        config.outputMainFrame.bpe = pgOutFrame->mBpp; //TODO: use bpe
    }

    // init and config p2p handle
    int ret = mPGParamAdapt->init(mPlatform, config);
    return ret;
}

// Support horizontal fragment only now
int PGCommon::calcFragmentCount(int overlap)
{
    int finalFragmentCount = 0;
    ia_css_data_terminal_manifest_t * data_terminal_manifest = nullptr;

    const ia_css_program_group_manifest_t *manifest =
            (const ia_css_program_group_manifest_t*)getCiprBufferPtr(mManifestBuffer);
    CheckError(!manifest, 1, "%s, can't get manifest ptr", __func__);

    for (int termIdx = 0; termIdx < mTerminalCount; termIdx++) {
        // Get max fragement size from manifest (align with 64)
        ia_css_terminal_manifest_t *terminal_manifest = ia_css_program_group_manifest_get_term_mnfst(manifest, termIdx);
        ia_css_terminal_type_t  terminal_type = ia_css_terminal_manifest_get_type(terminal_manifest);

        if (!((terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT) || (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN))) {
            continue;
        }

        data_terminal_manifest = ia_css_program_group_manifest_get_data_terminal_manifest(manifest, termIdx);
        CheckError(!data_terminal_manifest, -1, "%s, can't get data terminal manifest for term %d", __func__, termIdx);

        uint16_t size[IA_CSS_N_DATA_DIMENSION] = {0};
        int ret = ia_css_data_terminal_manifest_get_max_size(data_terminal_manifest, size);
        CheckError(ret < 0, 1, "%s: get max fragment size error for term %d", __func__, termIdx);

        size[IA_CSS_COL_DIMENSION] = ALIGN_64(size[IA_CSS_COL_DIMENSION]);
        // Overwrite the max value if need

        // Calc fragment count for terminal (only for horizontal direction)
        int maxFragmentWidth = size[IA_CSS_COL_DIMENSION];
        FrameInfo config;
        if (mTerminalFrameInfos.find(termIdx) != mTerminalFrameInfos.end()) {
            config = mTerminalFrameInfos[termIdx];
        }
        int fragmentCovered = maxFragmentWidth;
        int fragmentCount = 1;
        /*
         * Calculate how many fragment frames can cover the whole frame.
         * Consider overlap between two fragment frames.
         * Example: frame width = 300, max fragment width = 100, overlap = 10
         *       0|------------------------------|300
         *  f1   0|----------|100
         *  f2           90|----------|190
         *  f3                   180|----------|280
         *  f4                            270|---|300
         */
        while (fragmentCovered < config.mWidth) {
            fragmentCovered += (maxFragmentWidth - overlap);
            fragmentCount++;
        }

        if (finalFragmentCount < fragmentCount) {
            finalFragmentCount = fragmentCount;
        }
    }

    LOG2("%s: final fragment count %d for pg %d", __func__, finalFragmentCount, mPGId);
    return finalFragmentCount;
}

int PGCommon::handlePGParams(const ia_css_frame_format_type* frameFormatTypes)
{
    int pgParamsSize = ia_css_sizeof_program_group_param(mProgramCount, mTerminalCount, mFragmentCount);

    mPGParamsBuffer = createUserPtrCiprBuffer(pgParamsSize);
    CheckError(!mPGParamsBuffer, NO_MEMORY, "%s, call createUserPtrCiprBuffer fail", __func__);

    ia_css_program_group_param_t* pgParamsBuf = (ia_css_program_group_param_t*)getCiprBufferPtr(mPGParamsBuffer);
    int ret = ia_css_program_group_param_init(pgParamsBuf, mProgramCount, mTerminalCount, mFragmentCount, frameFormatTypes);
    CheckError((ret != OK), ret, "%s, call ia_css_program_group_param_init fail", __func__);

    if (mPPG) {
        ret = ia_css_program_group_param_set_protocol_version(
                pgParamsBuf,
                IA_CSS_PROCESS_GROUP_PROTOCOL_PPG);
        CheckError((ret != OK), ret, "%s, call ia_css_program_group_param_set_protocol_version fail", __func__);
    }
    return ret;
}

int PGCommon::setKernelBitMap()
{
    ia_css_program_group_param_t* pgParamsBuf = (ia_css_program_group_param_t*)getCiprBufferPtr(mPGParamsBuffer);
    LOG1("%s: mKernelBitmap: %#018lx", __func__, mKernelBitmap);
    int ret = ia_css_program_group_param_set_kernel_enable_bitmap(pgParamsBuf, mKernelBitmap);
    CheckError((ret != OK), ret, "%s, call ia_css_program_group_param_set_kernel_enable_bitmap fail", __func__);

    return ret;
}

int PGCommon::setTerminalParams(const ia_css_frame_format_type* frameFormatTypes)
{
    ia_css_program_group_param_t* pgParamsBuf =
        (ia_css_program_group_param_t*)getCiprBufferPtr(mPGParamsBuffer);
    ia_css_program_group_manifest_t* pg_manifest =
        (ia_css_program_group_manifest_t*)getCiprBufferPtr(mManifestBuffer);

    for (int i = 0; i < mTerminalCount; i++) {
        ia_css_terminal_param_t *terminalParam =
            ia_css_program_group_param_get_terminal_param(pgParamsBuf, i);
        CheckError(!terminalParam, UNKNOWN_ERROR, "%s, call ia_css_program_group_param_get_terminal_param fail", __func__);
        ia_css_terminal_manifest_t *terminal_manifest = ia_css_program_group_manifest_get_term_mnfst(pg_manifest, i);
        ia_css_terminal_type_t  terminal_type = ia_css_terminal_manifest_get_type(terminal_manifest);
        if (!((terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT) || (terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN))) {
            continue;
        }

        FrameInfo config = mTerminalFrameInfos[i];
        terminalParam->frame_format_type = frameFormatTypes[i];
        terminalParam->dimensions[IA_CSS_COL_DIMENSION] = config.mWidth;
        terminalParam->dimensions[IA_CSS_ROW_DIMENSION] = config.mHeight;
        terminalParam->fragment_dimensions[IA_CSS_COL_DIMENSION] = config.mWidth;
        terminalParam->fragment_dimensions[IA_CSS_ROW_DIMENSION] = config.mHeight;

        terminalParam->bpp = PGUtils::getCssBpp(config.mFormat);
        terminalParam->bpe = terminalParam->bpp;
        terminalParam->stride = PGUtils::getCssStride(config.mFormat, config.mWidth);

        terminalParam->offset = 0;
        terminalParam->index[IA_CSS_COL_DIMENSION] = 0;
        terminalParam->index[IA_CSS_ROW_DIMENSION] = 0;

        LOG2("%s: setTerminalParams: index=%d, format=%d, w=%d, h=%d, fw=%d, fh=%d, bpp=%d, bpe=%d, stride=%d, offset=%d, col=%d, row=%d",
             getName(), i,
             terminalParam->frame_format_type,
             terminalParam->dimensions[IA_CSS_COL_DIMENSION],
             terminalParam->dimensions[IA_CSS_ROW_DIMENSION],
             terminalParam->fragment_dimensions[IA_CSS_COL_DIMENSION],
             terminalParam->fragment_dimensions[IA_CSS_ROW_DIMENSION],
             terminalParam->bpp,
             terminalParam->bpe,
             terminalParam->stride,
             terminalParam->offset,
             terminalParam->index[IA_CSS_COL_DIMENSION],
             terminalParam->index[IA_CSS_ROW_DIMENSION]);
    }

    return OK;
}

int PGCommon::configureFragmentDesc()
{
    int num = mTerminalCount * mFragmentCount;
    std::unique_ptr<ia_p2p_fragment_desc[]> srcFragDesc =
                    std::unique_ptr<ia_p2p_fragment_desc[]>(new ia_p2p_fragment_desc[num]);
    int count = mPGParamAdapt->getFragmentDescriptors(num, srcFragDesc.get());
    CheckError(!count, UNKNOWN_ERROR, "getFragmentDescriptors fails");

    for (int termIdx = 0; termIdx < mTerminalCount; termIdx++) {
        if (mPgTerminals[termIdx] >= IPU_MAX_TERMINAL_COUNT) {
            continue;
        }

        ia_css_terminal_t* terminal = ia_css_process_group_get_terminal(mProcessGroup, mPgTerminals[termIdx]);
        ia_css_terminal_type_t terminalType = ia_css_terminal_get_type(terminal);
        if (!((terminalType == IA_CSS_TERMINAL_TYPE_DATA_OUT) || (terminalType == IA_CSS_TERMINAL_TYPE_DATA_IN))) {
            continue;
        }
        configureTerminalFragmentDesc(termIdx, &srcFragDesc[termIdx]);
    }
    return OK;
}

int PGCommon::configureTerminalFragmentDesc(int termIdx, const ia_p2p_fragment_desc* srcDesc)
{
#define DDR_WORD_BYTES 64
    ia_css_terminal_t* terminal = ia_css_process_group_get_terminal(mProcessGroup, mPgTerminals[termIdx]);
    ia_css_terminal_type_t terminalType = ia_css_terminal_get_type(terminal);
    if (!((terminalType == IA_CSS_TERMINAL_TYPE_DATA_OUT) || (terminalType == IA_CSS_TERMINAL_TYPE_DATA_IN))) {
        return OK;
    }

    bool vectorized = false;
    int packed_multiplier = 1;
    int packed_divider = 1;
    int dimension_bpp = PGUtils::getCssBpp(mTerminalFrameInfos[termIdx].mFormat);

    switch(mFrameFormatType[termIdx]) {
    case IA_CSS_DATA_FORMAT_BAYER_VECTORIZED:
    case IA_CSS_DATA_FORMAT_BAYER_LINE_INTERLEAVED:
        vectorized = true;
        dimension_bpp = (uint8_t) ALIGN_8(PGUtils::getCssBpp(mTerminalFrameInfos[termIdx].mFormat));
        break;
    case IA_CSS_DATA_FORMAT_RAW:
        dimension_bpp = (uint8_t) ALIGN_8(PGUtils::getCssBpp(mTerminalFrameInfos[termIdx].mFormat));
        break;
    case IA_CSS_DATA_FORMAT_BAYER_GRBG:
    case IA_CSS_DATA_FORMAT_BAYER_RGGB:
    case IA_CSS_DATA_FORMAT_BAYER_BGGR:
    case IA_CSS_DATA_FORMAT_BAYER_GBRG:
        dimension_bpp = (uint8_t) ALIGN_8(PGUtils::getCssBpp(mTerminalFrameInfos[termIdx].mFormat));
        break;
    case IA_CSS_DATA_FORMAT_YYUVYY_VECTORIZED:
        dimension_bpp = (uint8_t) (PGUtils::getCssBpp(mTerminalFrameInfos[termIdx].mFormat) * 3 / 2);
        packed_multiplier = 3;
        packed_divider = 2;
        vectorized = true;
        break;
    default:
        break;
    }

    for (int fragIdx = 0; fragIdx < mFragmentCount; fragIdx++) {
        ia_css_fragment_descriptor_t* dstFragDesc =
                ia_css_data_terminal_get_fragment_descriptor((ia_css_data_terminal_t*)terminal, fragIdx);
        CheckError(!dstFragDesc, -1, "%s: Can't get frag desc from terminal", __func__);

        dstFragDesc->dimension[IA_CSS_COL_DIMENSION] = srcDesc[fragIdx].fragment_width;
        dstFragDesc->dimension[IA_CSS_ROW_DIMENSION] = srcDesc[fragIdx].fragment_height;
        dstFragDesc->index[IA_CSS_COL_DIMENSION] = (uint16_t)
                (((srcDesc[fragIdx].fragment_start_x * packed_multiplier)
                 / packed_divider) * (vectorized ? 2 : 1));
        dstFragDesc->index[IA_CSS_ROW_DIMENSION] = (uint16_t)
                (srcDesc[fragIdx].fragment_start_y / (vectorized ? 2 : 1));

        int colOffset = 0;
        int pixels_per_word = 0;
        switch (mFrameFormatType[termIdx]) {
        case IA_CSS_DATA_FORMAT_YUV420:
        case IA_CSS_DATA_FORMAT_YYUVYY_VECTORIZED:
        case IA_CSS_DATA_FORMAT_BAYER_VECTORIZED:
            /** \todo Fragmentation with DMA packed formats is still open, need to
             * check this again when it is more clear (see #H1804344344).
             */
            pixels_per_word = (uint16_t) floor(DDR_WORD_BYTES * 8 / dimension_bpp);
            colOffset = (uint16_t) (floor(dstFragDesc->index[IA_CSS_COL_DIMENSION] / pixels_per_word) * DDR_WORD_BYTES);
            colOffset = (uint16_t) (colOffset + (((dstFragDesc->index[IA_CSS_COL_DIMENSION] % pixels_per_word) * dimension_bpp) / 8));
            break;
        default:
            colOffset = (uint16_t) (dstFragDesc->index[IA_CSS_COL_DIMENSION] * dimension_bpp / 8);
            break;
        }

        dstFragDesc->offset[IA_CSS_COL_DIMENSION] = (uint16_t)colOffset;
        dstFragDesc->offset[IA_CSS_ROW_DIMENSION] = dstFragDesc->index[IA_CSS_ROW_DIMENSION];

        LOG2("%s: %d:%d: get frag desc %d (%d, %d, %d, %d)", __func__, mPGId, termIdx, fragIdx,
             srcDesc[fragIdx].fragment_width, srcDesc[fragIdx].fragment_height,
             srcDesc[fragIdx].fragment_start_x, srcDesc[fragIdx].fragment_start_y);
        LOG2("%s: %d:%d:       frag %d: size(%d, %d) index(%d, %d), offset(%d, %d)", __func__, mPGId, termIdx,fragIdx,
             dstFragDesc->dimension[IA_CSS_COL_DIMENSION],
             dstFragDesc->dimension[IA_CSS_ROW_DIMENSION],
             dstFragDesc->index[IA_CSS_COL_DIMENSION],
             dstFragDesc->index[IA_CSS_ROW_DIMENSION],
             dstFragDesc->offset[IA_CSS_COL_DIMENSION],
             dstFragDesc->offset[IA_CSS_ROW_DIMENSION]);
    }
    return OK;
}

int PGCommon::iterate(CameraBufferMap &inBufs, CameraBufferMap &outBufs,
                      ia_binary_data *statistics, const ia_binary_data *ipuParameters)
{
    LOG2("%s:%s ++", getName(), __func__);

    long sequence = 0;
    if (!inBufs.empty()) {
        sequence = inBufs.begin()->second->getSequence();
    }

    int ret = prepareTerminalBuffers(ipuParameters, inBufs, outBufs, sequence);
    CheckError((ret != OK), ret, "%s, prepareTerminalBuffers fail with %d", getName(), ret);

    // Create PPG & PPG start/stop commands at the beginning
    if (mPPG && !mPPGBuffer) {
        ia_css_program_group_param_t* pgParamsBuf =
            (ia_css_program_group_param_t*)getCiprBufferPtr(mPGParamsBuffer);
        ia_css_program_group_manifest_t* manifestBuf =
            (ia_css_program_group_manifest_t*)getCiprBufferPtr(mManifestBuffer);

        size_t pgSize = ia_css_sizeof_process_group(manifestBuf, pgParamsBuf);

        mPPGBuffer = createUserPtrCiprBuffer(pgSize);
        CheckError(!mPPGBuffer, NO_MEMORY, "%s, call createUserPtrCiprBuffer fail", __func__);
        mPPGProcessGroup = (ia_css_process_group_t*)getCiprBufferPtr(mPPGBuffer);
        MEMCPY_S(mPPGProcessGroup, pgSize, mProcessGroup, ia_css_process_group_get_size(mProcessGroup));

    }
    if (!mCmd) {
        ret = createCommands();
       CheckError((ret != OK), ret, "%s, call createCommands fail", __func__);
    }

    if (mPPG && !mPPGStarted) {
        ret = startPPG();
        CheckError((ret != OK), ret, "%s, startPPG fail", getName());
        mPPGStarted = true;
    }

    ret = executePG();
    CheckError((ret != OK), ret, "%s, executePG fail", getName());

    if (statistics) {
        ret = mPGParamAdapt->decode(mTerminalCount, mParamPayload, statistics);
        CheckError((ret != OK), ret, "%s, decode fail", getName());
    }

    postTerminalBuffersDone(sequence);
    LOG2("%s:%s -- ", getName(), __func__);
    return ret;
}

int PGCommon::preparePayloadBuffers() {
    int count = mPGParamAdapt->getPayloadSizes(mTerminalCount, mParamPayload);
    CheckError((count != mTerminalCount), NO_MEMORY, "%s, getPayloadSize fails", __func__);

    // For TNR parameter refer terminals
    int ret = allocateTnrSimBuffers();
    CheckError((ret != OK), NO_MEMORY, "%s, allocateTnrSimBuffers fails", __func__);

    // For other normal terminals
    std::vector<ia_binary_data> payloads;
    ia_binary_data payload = {nullptr, 0};
    for (int termIdx = 0; termIdx < mTerminalCount; termIdx++) {
        if (mParamPayload[termIdx].data) {
            payload.size = 0;  // allocated
        } else {
            payload.size = mParamPayload[termIdx].size;
        }
        payloads.push_back(payload);
    }
    ret = mPGParamAdapt->allocatePayloads(payloads.size(), payloads.data());
    CheckError(ret != OK, NO_MEMORY, "%s, allocate payloads fail", __func__);
    for (int i = 0; i < mTerminalCount; i++) {
        if (payloads[i].data) {
            CIPR::Buffer* ciprBuf = registerUserBuffer(payloads[i].size, payloads[i].data);
            CheckError(!ciprBuf, NO_MEMORY, "%s, register payload buffer %p for term %d fail",
                       __func__, payloads[i].data, i);
            memset(payloads[i].data, 0, PAGE_ALIGN(payloads[i].size));
            mParamPayload[i].data = payloads[i].data;
            mTerminalBuffers[i] = ciprBuf;
        }
    }

    return OK;
}

int PGCommon::allocateTnrDataBuffers() {
    if (mTnrTerminalPair.inId < 0 || !mTnrDataBuffers.empty()) return OK;

    // port = term index + 1
    int32_t termIndex = mTnrTerminalPair.inId;
    int64_t referId = ShareReferBufferPool::constructReferId(mStreamId, mPGId, termIndex + 1);
    int32_t bufferCount = PAIR_BUFFER_COUNT;
    if (mShareReferPool.get()) {
        bufferCount = mShareReferPool->getMinBufferNum(referId);
        if (bufferCount) {
            mShareReferIds[termIndex] = referId;  // mShareReferPool supports for the refer buffers
        }
    }
    if (bufferCount < PAIR_BUFFER_COUNT) {
        bufferCount = PAIR_BUFFER_COUNT;
    }

    int size = CameraUtils::getFrameSize(mTerminalFrameInfos[mInputMainTerminal].mFormat,
                                         mTerminalFrameInfos[mInputMainTerminal].mWidth,
                                         mTerminalFrameInfos[mInputMainTerminal].mHeight);
    for (int32_t i = 0; i < bufferCount; i++) {
        uint8_t* buffer = nullptr;
        int ret = posix_memalign((void**)&buffer, PAGE_SIZE_U, PAGE_ALIGN(size));
        CheckError(ret, NO_MEMORY, "%s, alloc %d tnr data buf fails", __func__, i);
        mTnrDataBuffers.push_back(buffer);

        CIPR::Buffer* ciprBuf = registerUserBuffer(size, buffer);
        CheckError(!ciprBuf, NO_MEMORY, "%s, register %d tnr buf %p fails", __func__, i, buffer);

        if (i == PAIR_BUFFER_IN_INDEX) mTerminalBuffers[mTnrTerminalPair.inId] = ciprBuf;
        else if (i == PAIR_BUFFER_OUT_INDEX) mTerminalBuffers[mTnrTerminalPair.outId] = ciprBuf;
        if (mShareReferIds[termIndex])
            mShareReferPool->registerReferBuffers(referId, ciprBuf);
    }

    return OK;
}

int PGCommon::allocateTnrSimBuffers() {
    for (auto pair : mTnrSimTerminalPairs) {
        int32_t inId = pair.inId;
        // port = term index + 1
        int64_t referId = ShareReferBufferPool::constructReferId(mStreamId, mPGId, inId + 1);
        int32_t bufferCount = PAIR_BUFFER_COUNT;
        if (mShareReferPool.get()) {
            bufferCount = mShareReferPool->getMinBufferNum(referId);
            if (bufferCount) {
                mShareReferIds[inId] = referId;  // flag it: get payload via mShareReferPool
            }
        }
        if (bufferCount < PAIR_BUFFER_COUNT) {
            bufferCount = PAIR_BUFFER_COUNT;
        }

        std::vector<ia_binary_data> payloads;
        ia_binary_data payload = {nullptr, mParamPayload[inId].size};
        for (int32_t i = 0; i < bufferCount; i++) {
            payloads.push_back(payload);
        }
        int ret = mPGParamAdapt->allocatePayloads(payloads.size(), payloads.data());
        CheckError(ret != OK, NO_MEMORY, "%s, allocate for term pair %d fail", __func__, inId);

        // Register all buffers and clear
        for (int32_t i = 0; i < bufferCount; i++) {
            CIPR::Buffer* ciprBuf = registerUserBuffer(payloads[i].size, payloads[i].data);
            CheckError(!ciprBuf, NO_MEMORY, "%s, register %d:%p for term pair %d fails",
                       __func__, i, payloads[i].data, inId);
            memset(payloads[i].data, 0, PAGE_ALIGN(payloads[i].size));

            if (mShareReferIds[inId])
                mShareReferPool->registerReferBuffers(referId, ciprBuf);

            // Set default payload for terminal pair to mark they are allocated.
            if (i == PAIR_BUFFER_IN_INDEX) {
                mParamPayload[pair.inId].data = payloads[PAIR_BUFFER_IN_INDEX].data;
                mTerminalBuffers[pair.inId] = ciprBuf;
            } else if (i == PAIR_BUFFER_OUT_INDEX) {
                mParamPayload[pair.outId].data = payloads[PAIR_BUFFER_OUT_INDEX].data;
                mTerminalBuffers[pair.outId] = ciprBuf;
            }
        }

    }
    return OK;
}

int PGCommon::prepareTerminalBuffers(const ia_binary_data *ipuParameters,
                                     const CameraBufferMap& inBufs, const CameraBufferMap& outBufs,
                                     long sequence) {
    CIPR::Buffer* ciprBuf = nullptr;
    // Prepare payload
    for (int termIdx = 0; termIdx < mTerminalCount; termIdx++) {
        // Payload for data terminals
        std::shared_ptr<CameraBuffer> buffer;
        ia_uid terminalUid = mTerminalBaseUid + termIdx;
        if (inBufs.find(terminalUid) != inBufs.end()) {
             buffer = inBufs.at(terminalUid);
        } else if (outBufs.find(terminalUid) != outBufs.end()) {
             buffer = outBufs.at(terminalUid);
        }

        if (buffer) {
            bool flush = buffer->getUsage() == BUFFER_USAGE_GENERAL ? true : false;
            ciprBuf = (buffer->getMemory() == V4L2_MEMORY_DMABUF) \
                     ? registerUserBuffer(buffer->getBufferSize(), buffer->getFd(), flush) \
                     : registerUserBuffer(buffer->getBufferSize(), buffer->getBufferAddr(), flush);
            CheckError(!ciprBuf, NO_MEMORY, "%s, register buffer size %d for terminal %d fail",
                       __func__, buffer->getBufferSize(), termIdx);
            mTerminalBuffers[termIdx] = ciprBuf;
        }
    }

    if (!mTnrDataBuffers.empty()) {
        if (mShareReferIds[mTnrTerminalPair.inId]) {
            mShareReferPool->acquireBuffer(mShareReferIds[mTnrTerminalPair.inId],
                                           &mTerminalBuffers[mTnrTerminalPair.inId],
                                           &mTerminalBuffers[mTnrTerminalPair.outId],
                                           sequence);
        } else {
            std::swap(mTerminalBuffers[mTnrTerminalPair.inId],
                      mTerminalBuffers[mTnrTerminalPair.outId]);
        }
    }

    for (auto& pair : mDvsTerminalPairs) {
        std::swap(mTerminalBuffers[pair.inId], mTerminalBuffers[pair.outId]);
    }

    for (auto& pair : mTnrSimTerminalPairs) {
        if (mShareReferIds[pair.inId]) {
            mShareReferPool->acquireBuffer(mShareReferIds[pair.inId],
                                           &mTerminalBuffers[pair.inId],
                                           &mTerminalBuffers[pair.outId],
                                           sequence);
        } else {
            std::swap(mTerminalBuffers[pair.inId], mTerminalBuffers[pair.outId]);
        }

        // Update palyload buffers
        mTerminalBuffers[pair.inId]->getMemoryCpuPtr(&mParamPayload[pair.inId].data);
        mTerminalBuffers[pair.outId]->getMemoryCpuPtr(&mParamPayload[pair.outId].data);
    }

    return mPGParamAdapt->updatePALAndEncode(ipuParameters, mTerminalCount, mParamPayload);
}

void PGCommon::postTerminalBuffersDone(long sequence) {
    if (!mTnrDataBuffers.empty() && mShareReferIds[mTnrTerminalPair.inId]) {
        mShareReferPool->releaseBuffer(mShareReferIds[mTnrTerminalPair.inId],
                                       mTerminalBuffers[mTnrTerminalPair.inId],
                                       mTerminalBuffers[mTnrTerminalPair.outId],
                                       sequence);
    }
    for (auto pair : mTnrSimTerminalPairs) {
        if (mShareReferIds[pair.inId]) {
            mShareReferPool->releaseBuffer(mShareReferIds[pair.inId],
                                           mTerminalBuffers[pair.inId],
                                           mTerminalBuffers[pair.outId],
                                           sequence);
        }
    }
}

int PGCommon::executePG()
{
    TRACE_LOG_PROCESS(mName.c_str(), __func__);
    CheckError((!mCmd), INVALID_OPERATION, "%s, Command is invalid.", __func__);
    CheckError((!mProcessGroup), INVALID_OPERATION, "%s, process group is invalid.", __func__);

    mCmd->getConfig(&mCmdCfg);
    int bufferCount = ia_css_process_group_get_terminal_count(mProcessGroup);
    mCmdCfg.id = mPGId;
    mCmdCfg.priority = 1;
    mCmdCfg.pgParamsBuf = mPPG ? nullptr : mPGParamsBuffer;
    mCmdCfg.pgManifestBuf = mManifestBuffer;
    mCmdCfg.pg = mPGBuffer;
    mCmdCfg.extBuf = mCmdExtBuffer;
    mCmdCfg.buffers.resize(bufferCount);

    for (int i = 0; i < bufferCount; i++) {
        ia_css_terminal_t *terminal = ia_css_process_group_get_terminal(mProcessGroup, i);
        CheckError(!terminal, UNKNOWN_ERROR, "failed to get terminal");
        mCmdCfg.buffers[i] = mTerminalBuffers[terminal->tm_index];
    }
    if (mPPG) {
         ia_css_process_group_set_token(mProcessGroup, mToken);
    }

    for (int fragIdx = 0; fragIdx < mFragmentCount; fragIdx++) {
        int ret = ia_css_process_group_set_fragment_state(mProcessGroup, (uint16_t)fragIdx);
        CheckError((ret != OK), ret, "%s, set fragment count %d fail %p", getName(), fragIdx, mProcessGroup);
        ret = ia_css_process_group_set_fragment_limit(mProcessGroup, (uint16_t)(fragIdx + 1));
        CheckError((ret != OK), ret, "%s, set fragment limit %d fail", getName(), fragIdx);

        ret = handleCmd(&mCmd, &mCmdCfg);
        CheckError((ret != OK), ret, "%s, call handleCmd fail", getName());
    }

    return OK;
}

int PGCommon::startPPG()
{
    // Get basic command config
    CIPR::PSysCommandConfig cmdCfg;
    mPPGCmd[PPG_CMD_TYPE_START]->getConfig(&cmdCfg);

    // Update config
    cmdCfg.id = mPGId;
    cmdCfg.priority = 1;
    cmdCfg.pgParamsBuf = mPPG ? nullptr : mPGParamsBuffer;
    cmdCfg.pgManifestBuf = mManifestBuffer;
    cmdCfg.pg = mPPGBuffer;
    cmdCfg.extBuf = mPPGCmdExtBuffer[PPG_CMD_TYPE_START];
    const int terminalCount = ia_css_process_group_get_terminal_count(mProcessGroup);
    cmdCfg.buffers.resize(terminalCount);
    std::fill(cmdCfg.buffers.begin(), cmdCfg.buffers.end(), nullptr);

    ia_css_process_group_set_fragment_state(mPPGProcessGroup, 0);
    ia_css_process_group_set_fragment_limit(mPPGProcessGroup, 1);

    int ret = handleCmd(&mPPGCmd[PPG_CMD_TYPE_START], &cmdCfg);
    mToken = ia_css_process_group_get_token(mPPGProcessGroup);
    return ret;
}

int PGCommon::stopPPG()
{
    CIPR::PSysCommandConfig cmdCfg;

    mPPGCmd[PPG_CMD_TYPE_STOP]->getConfig(&cmdCfg);

    cmdCfg.id = mCmdCfg.id;
    cmdCfg.priority = mCmdCfg.priority;
    cmdCfg.pgParamsBuf = mCmdCfg.pgParamsBuf;
    cmdCfg.pgManifestBuf = mCmdCfg.pgManifestBuf;
    cmdCfg.pg = mPPGBuffer;
    cmdCfg.extBuf = mPPGCmdExtBuffer[PPG_CMD_TYPE_STOP];
    cmdCfg.buffers.resize(0);

    int ret =  handleCmd(&mPPGCmd[PPG_CMD_TYPE_STOP], &cmdCfg);
    return ret;
}

int PGCommon::handleCmd(CIPR::Command** cmd, CIPR::PSysCommandConfig* cmdCfg)
{
    CIPR::PSysEventConfig eventCfg = {};
    mEvent->getConfig(&eventCfg);
    cmdCfg->issueID = reinterpret_cast<uint64_t>(cmd);
    eventCfg.commandIssueID = cmdCfg->issueID;

    CIPR::Result ret = (*cmd)->setConfig(*cmdCfg);
    CheckError((ret != CIPR::Result::OK), UNKNOWN_ERROR, "%s, call CIPR::Command::setConfig fail", __func__);

    ret = (*cmd)->getConfig(cmdCfg);
    CheckError((ret != CIPR::Result::OK), UNKNOWN_ERROR, "%s, call CIPR::Command::getConfig fail", __func__);

    ret = (*cmd)->enqueue(mCtx);
    CheckError((ret != CIPR::Result::OK), UNKNOWN_ERROR, "%s, call Context::enqueueCommand() fail %d", __func__, ret);

    // Wait event
    ret = mEvent->wait(mCtx);
    CheckError((ret != CIPR::Result::OK), UNKNOWN_ERROR, "%s, call Context::waitForEvent fail, ret: %d", __func__, ret);

    ret = mEvent->getConfig(&eventCfg);
    CheckError((ret != CIPR::Result::OK), UNKNOWN_ERROR, "%s, call Event::getConfig() fail, ret: %d", __func__, ret);
    // Ignore the error in event config since it's not a fatal error.
    if (eventCfg.error) {
        LOGW("%s, event config error: %d", __func__, eventCfg.error);
    }

    return (eventCfg.error == 0) ? OK : UNKNOWN_ERROR;
}

int PGCommon::getCapability()
{
    CIPR::PSYSCapability cap;
    int ret = OK;
    CIPR::Result err = mCtx->getCapabilities(&cap);
    CheckError((err != CIPR::Result::OK), UNKNOWN_ERROR, "Call Context::getCapabilities() fail, ret:%d", ret);

    LOG1("%s: capability.version:%d", __func__, cap.version);
    LOG1("%s: capability.driver:%s", __func__, cap.driver);
    LOG1("%s: capability.devModel:%s", __func__, cap.devModel);
    LOG1("%s: capability.programGroupCount:%d", __func__, cap.programGroupCount);
    mPGCount = cap.programGroupCount;

    if (strncmp((char *)cap.devModel, "ipu4p", 5) == 0) {
        mPlatform = IA_P2P_PLATFORM_CNL_B0;
        LOG1("%s: cnl/icl/ksl shared the same p2p platform id", __func__);
    } else if (strncmp((char *)cap.devModel, "ipu4", 4) == 0) {
        switch (cap.devModel[13]) {
            case 'B':
                 mPlatform = IA_P2P_PLATFORM_BXT_B0;
                 break;
            default:
                 LOGE("%s: unsupported psys device model :%s", __func__, cap.devModel);
                 ret = BAD_VALUE;
                 break;
        }
    } else if (strncmp((char *)cap.devModel, "ipu6", 4) == 0) {
        mPlatform = IA_P2P_PLATFORM_IPU6;
        mPPG = true;
    } else {
        LOGE("%s: unsupported psys device model : %s", __func__, cap.devModel);
        ret = BAD_VALUE;
    }

    return ret;
}

int PGCommon::getManifest(int pgId)
{
    int i = 0;

    for (; i < mPGCount; i++) {
        CIPR::Buffer* manifestBuffer = nullptr;
        int programCount = 0;
        int terminalCount = 0;
        int programGroupId = 0;
        int manifestSize = 0;
        ia_css_kernel_bitmap_t kernelBitmap = ia_css_kernel_bitmap_clear();
        uint32_t size = 0;

        CIPR::Result ret = mCtx->getManifest(i, &size, nullptr);
        if (ret != CIPR::Result::OK) continue;
        CheckError((size == 0), UNKNOWN_ERROR, "%s, the manifest size is 0", __func__);

        manifestBuffer = createUserPtrCiprBuffer(size);
        CheckError(!manifestBuffer, NO_MEMORY, "%s, call createUserPtrCiprBuffer fail", __func__);

        void* manifest = getCiprBufferPtr(manifestBuffer);

        ret = mCtx->getManifest(i, &size, manifest);
        if (ret != CIPR::Result::OK) {
            LOGE("%s, call Context::getManifest() fail", __func__);
            delete manifestBuffer;
            return UNKNOWN_ERROR;
        }

        LOG1("%s: pg index: %d, manifest size: %u", __func__, i, size);
        const ia_css_program_group_manifest_t *mf = (const ia_css_program_group_manifest_t*)manifest;
        programCount = ia_css_program_group_manifest_get_program_count(mf);
        terminalCount = ia_css_program_group_manifest_get_terminal_count(mf);
        programGroupId = ia_css_program_group_manifest_get_program_group_ID(mf);
        manifestSize = ia_css_program_group_manifest_get_size(mf);
        kernelBitmap = ia_css_program_group_manifest_get_kernel_bitmap(mf);

        LOG1("%s: pgIndex: %d, programGroupId: %d, manifestSize: %d, programCount: %d, terminalCount: %d",
             __func__, i, programGroupId, manifestSize, programCount, terminalCount);

        if (pgId == programGroupId) {
            mProgramCount = programCount;
            mTerminalCount = terminalCount;
            mManifestSize = manifestSize;
            mKernelBitmap = kernelBitmap;
            mManifestBuffer = manifestBuffer;
            break;
        }

        delete manifestBuffer;
    }

    CheckError((i == mPGCount), BAD_VALUE, "%s, Can't found available pg: %d", __func__, pgId);

    return OK;
}

CIPR::Buffer* PGCommon::createDMACiprBuffer(int size, int fd, bool flush)
{
    CIPR::MemoryFlag deviceFlags = CIPR::MemoryFlag::MemoryHandle;
    if (!flush) deviceFlags |= CIPR::MemoryFlag::NoFlush;

    CIPR::MemoryDesc mem;
    mem.size = size;
    mem.flags = CIPR::MemoryFlag::MemoryHandle | CIPR::MemoryFlag::HardwareOnly;
    mem.handle = fd;
    mem.cpuPtr = nullptr;
    mem.anchor = nullptr;

    CIPR::Buffer* buf = new CIPR::Buffer(size, mem.flags | deviceFlags, &mem);

    CIPR::Result ret = buf->attatchDevice(mCtx);
    if (ret != CIPR::Result::OK) {
        LOGE("%s, call Buffer::attatchDevice() fail", __func__);
        delete buf;
        return nullptr;
    }

    return buf;
}

CIPR::Buffer* PGCommon::createUserPtrCiprBuffer(int size, void* ptr, bool flush)
{
    CIPR::Buffer* buf = nullptr;
    if (ptr == nullptr) {
        buf = new CIPR::Buffer(size, CIPR::MemoryFlag::AllocateCpuPtr | CIPR::MemoryFlag::NoFlush,
                               nullptr);
    } else {
        CIPR::MemoryDesc mem;
        mem.size = size;
        mem.flags = CIPR::MemoryFlag::CpuPtr;
        if (!flush) mem.flags |= CIPR::MemoryFlag::NoFlush;
        mem.handle = 0;
        mem.cpuPtr = ptr;
        mem.anchor = nullptr;
        buf = new CIPR::Buffer(size, CIPR::MemoryFlag::CpuPtr, &mem);
    }

    CIPR::Result ret = buf->attatchDevice(mCtx);
    if (ret != CIPR::Result::OK) {
        LOGE("%s, call Buffer::attatchDevice() fail", __func__);
        delete buf;
        return nullptr;
    }

    return buf;
}

void* PGCommon::getCiprBufferPtr(CIPR::Buffer* buffer)
{
    CheckError(!buffer, nullptr, "%s, invalid cipr buffer", __func__);

    void* ptr = nullptr;
    CIPR::Result ret = buffer->getMemoryCpuPtr(&ptr);
    CheckError((ret != CIPR::Result::OK), nullptr, "%s, call Buffer::getMemoryCpuPtr() fail", __func__);

    return ptr;
}

int PGCommon::getCiprBufferSize(CIPR::Buffer* buffer)
{
    CheckError(!buffer, BAD_VALUE, "%s, invalid cipr buffer", __func__);

    int size = 0;
    CIPR::Result ret = buffer->getMemorySize(&size);
    CheckError((ret != CIPR::Result::OK), NO_MEMORY, "%s, call Buffer::getMemorySize() fail", __func__);

    return size;
}

CIPR::Buffer* PGCommon::registerUserBuffer(int size, void* ptr, bool flush)
{
    CheckError((size <= 0 || ptr == nullptr), nullptr, "Invalid parameter: size=%d, ptr=%p", size, ptr);

    for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
        if (ptr == it->userPtr) {
            if (size == getCiprBufferSize(it->ciprBuf)) {
                return it->ciprBuf;
            }

            LOG2("%s, the buffer size is changed: old(%d), new(%d) addr(%p)",
                 __func__, getCiprBufferSize(it->ciprBuf), size, it->userPtr);
            delete it->ciprBuf;
            it->ciprBuf = nullptr;
            it->userPtr = nullptr;
            mBuffers.erase(it);
            break;
        }
    }

    CIPR::Buffer* ciprBuf = createUserPtrCiprBuffer(size, ptr, flush);
    CheckError(!ciprBuf, nullptr, "Create cipr buffer for %p failed", ptr);

    CiprBufferMapping bufMap;
    bufMap.userPtr = ptr;
    bufMap.ciprBuf = ciprBuf;
    mBuffers.push_back(bufMap);

    return ciprBuf;
}

CIPR::Buffer* PGCommon::registerUserBuffer(int size, int fd, bool flush)
{
    CheckError((size <= 0 || fd < 0), nullptr, "Invalid parameter: size: %d, fd: %d", size, fd);

    for (auto it = mBuffers.begin(); it != mBuffers.end(); ++it) {
        if (fd == it->userFd) {
            if (size == getCiprBufferSize(it->ciprBuf)) {
                return it->ciprBuf;
            }

            LOG2("%s, the buffer size is changed: old(%d), new(%d) fd(%d)",
                 __func__, getCiprBufferSize(it->ciprBuf), size, it->userFd);
            delete it->ciprBuf;
            it->ciprBuf = nullptr;
            it->userFd = -1;
            mBuffers.erase(it);
            break;
        }
    }

    CIPR::Buffer* ciprBuf = createDMACiprBuffer(size, fd, flush);
    CheckError(!ciprBuf, nullptr, "Create cipr buffer for fd %d failed", fd);

    CiprBufferMapping bufMap;
    bufMap.userFd = fd;
    bufMap.ciprBuf = ciprBuf;
    mBuffers.push_back(bufMap);

    return ciprBuf;
}

void PGCommon::dumpTerminalPyldAndDesc(int pgId, long sequence, ia_css_process_group_t* pgGroup)
{
    if (!CameraDump::isDumpTypeEnable(DUMP_PSYS_PG)) return;

    char fileName[MAX_NAME_LEN] = {'\0'};
    uint32_t pgSize = ia_css_process_group_get_size(pgGroup);
    snprintf(fileName, (MAX_NAME_LEN - 1), "hal_pg_%d_%ld.bin", pgId, sequence);

    FILE *fp = fopen (fileName, "w+");
    CheckError(fp == nullptr, VOID_VALUE, "open dump file %s failed", fileName);
    const unsigned int* printPtr = (const unsigned int*)pgGroup;
    fprintf(fp, "::pg dump size %d(0x%x)\n", pgSize, pgSize);
    for (unsigned int i = 0; i < pgSize / sizeof(*printPtr); i++) {
        fprintf(fp, "%08x\n", printPtr[i]);
    }

    int terminalCount = ia_css_process_group_get_terminal_count(pgGroup);
    for (int i = 0; i < terminalCount; i++) {
        ia_css_terminal_t *terminal = ia_css_process_group_get_terminal(pgGroup, i);
        if (!terminal) {
            LOGE("failed to get terminal");
            fclose(fp);
            return;
        }
        if (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN
            || terminal->terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT) {
            continue;
        }

        void* ptr = getCiprBufferPtr(mTerminalBuffers[terminal->tm_index]);
        int size = getCiprBufferSize(mTerminalBuffers[terminal->tm_index]);
        const char* typeStr = (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_DATA_IN) ? "DATA_IN"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_DATA_OUT) ? "DATA_OUT"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_STREAM) ? "PARAM_STREAM"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_IN) ? "CACHED_IN"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_CACHED_OUT) ? "CACHED_OUT"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_IN) ? "SPATIAL_IN"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SPATIAL_OUT) ? "SPATIAL_OUT"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_IN) ? "SLICED_IN"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PARAM_SLICED_OUT) ? "SLICED_OU"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_STATE_IN) ? "STATE_IN"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_STATE_OUT) ? "STATE_OUT"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM) ? "PROGRAM"
                            : (terminal->terminal_type == IA_CSS_TERMINAL_TYPE_PROGRAM_CONTROL_INIT) ? "PROGRAM_CONTROL_INIT"
                            :                                                             "UNKNOWN";
        printPtr = (const unsigned int*)ptr;
        fprintf(fp, "::terminal %d dump size %d(0x%x), line %d, type %s\n", terminal->tm_index, size, size, PAGE_ALIGN(size)/4, typeStr);
        for (unsigned int i = 0; i < PAGE_ALIGN(size) / sizeof(*printPtr); i++) {
            fprintf(fp, "%08x\n", printPtr[i]);
        }
    }

    fclose (fp);
}

} // namespace icamera
