/*
 * Copyright (C) 2024 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.
 */

#ifndef INTEL_CCA_H_
#define INTEL_CCA_H_

#include "IntelCCABase.h"
#include "IIPUAic.h"

namespace cca {

/*!
 * \brief main entrance of CCA Flow lib.
 */
class LIBEXPORT IntelCCA : public IntelCCABase {
 public:
    IntelCCA();
    virtual ~IntelCCA();

    /*!
     *
     * \brief reinit aic
     *
     * \param [in]  aic_id       Mandatory.\n
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err reinitAic(const int32_t aic_id = -1);

    /*!
     *
     * \brief reinit aiq
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err reinitAiq();

    /*!
     *
     * \brief configure the kernels of pipeline, register all kernel's offset, and return the terminal
     *  number and payload size
     *
     * \param [in]  conf         kernel list for the pipeline
     * \param [in]  offset       kernel offsets
     * \param [out] termConfig   terminal payload number and size
     * \param [in]  aicId        (Optional) The id for aic handle
     * \param statsBufToTermId   (Optional) Mapping from statistics buffer type to terminal ID
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err configAIC(const cca_aic_config &conf, const cca_aic_kernel_offset &offset,
                     cca_aic_terminal_config &termConfig, int32_t aicId = -1, const int32_t* statsBufToTermId = nullptr);

    /*!
     *
     * \brief register payload buffers to AIC
     * \param [out] termConfig   terminal payload
     * \param [in]  aicId        (Optional)The id for aic handle
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err registerAICBuf(const cca_aic_terminal_config &termConfig, int32_t aicId = -1);

    /*!
     *
     * \brief query the PAL buffer filled by kernel parameters calculated by AIC
     * \param [out] termConfig   terminal payload
     * \param [in]  aicId        (Optional)The id for aic handle
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err getAICBuf(cca_aic_terminal_config &termConfig, int32_t aicId = -1);

    /*!
     *
     * \brief Decode statistics from HW.
     * Parse and decode different statistics from HW including AE/AWB/DVS/HDR
     *
     * \param [in]  groupId      statistics binary generated by CB (groupId)
     * \param [in]  seqId        statistics sequence number
     * \param [in]  aicId        (Optional)The id for aic handle
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err decodeStats(int32_t groupId, int64_t seqId, int32_t aicId = -1);

    /*!
     *
     * \brief  run AIC to get PAL binary for IPU7 HW.
     *  Calculate the PAL parameters according to 3A+ results and manual settings
     *
     * \param [in]  frameId      indicate PAL results for specia frame
     * \param [in]  params       manual settings for IPU pipeline
     * \param [in]  bitmap       bitmap to decide which CB will be run
     * \param[in]   aicId        Optional. id for aic handle.
     * \param [out] output       binary array of IPU parameters for each CB
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err runAIC (uint64_t frameId, const cca_pal_input_params& params,
                   cca_multi_pal_output& output, uint8_t bitmap = UINT8_MAX, int32_t aicId = -1);

    ia_err GetPalInputData(uint32_t stream_id, int32_t seq_id, ia_binary_data* aic_output_common, ia_binary_data* tuning_output, int32_t aicId = -1);

    /*!
     *
     * \brief  run AIC to get PAL binary for IPU7 HW.
     *  Calculate the PAL parameters according to 3A+ results and manual settings
     *
     * \param [in]  frameId      indicate PAL results for specia frame
     * \param [in]  params       manual settings for IPU pipeline
     * \param[in]   aicId        Optional. id for aic handle.
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err runAIC(uint64_t frameId, const cca_pal_input_params &params, int32_t aicId = -1);

    /*!
     *
     * \brief  run AIC to get PAL binary for IPU7 HW.
     *  Calculate the PAL parameters according to 3A+ results and manual settings
     *
     * \param [in]  frameId      indicate PAL results for specia frame
     * \param [in]  groupId      statistics binary generated by CB (groupId)
     * \param [in]   aicId       Optional. id for aic handle.
     * \param [out] output       binary array of IPU parameters for each CB
     *
     * \return                   Error code for status. zero on success, non-zero on failure
     */
    ia_err runKernels(uint32_t groupId, uint64_t frameId, cca_binary_data *output_data, uint32_t fragment_index = 0U, int32_t aicId = -1);

    static  uint32_t getPacOutputSize(const cca_program_group& programGroup);

    ia_err updateConfigurationResolutions(const cca_aic_config& conf, int32_t aicId, bool isKeyResolutionChanged);

    cca_frame_stats* queryStatsBuf(cca_stats_buf_status status, uint64_t frameId = cca::INVALID_FRAME_ID);

 private:
    /*!
     * \brief Set input statistics and information (e.g faces) about the captured image.
     * CCA Flow algorithms need various information about the conditions in which the frame and
     * statistics were captured in order to calculate new parameters.
     *
     * \param[in] params                Mandatory.\n
     *                                  Input parameters containing statistics information about a
     * frame.
     *
     * \param[in] aiqResults            Mandatory.\n
     *                                  AIQ results from corresponding frame.
     *
     * \return                          Error code for status. zero on success, non-zero on failure
     */
    virtual ia_err setStatsToAiq(const cca_stats_params &params, const cca_aiq_results_storage &aiqResults) override;

    virtual ia_err setLtmTuning(const ia_binary_data *tuning_data_ptr) override {
        (void)tuning_data_ptr;
        return ia_err_none;
    };
    virtual void updateLtmResult(cca_3a_plus_results* results) override {
        if (results != nullptr) {
            results->drc_params = nullptr;
            results->ltm_results = nullptr;
        }
    }

    virtual void newAic() override;
    virtual void deleteAic() override;
    virtual ia_err initAic(const ia_binary_data *aiqb, const ia_cmc_t *cmc, uint32_t max_stats_width,
                           uint32_t max_stats_height, uint32_t max_num_stats_in, const ia_mkn *mkn,
                           const cca_stream_ids& aic_stream_ids) override;
    virtual ia_err updateAicTuning(const ia_binary_data *aiqb, const ia_cmc_t *cmc, int32_t streamId = -1) override;
    virtual ia_err getDvsStatsAic(ia_dvs_statistics* stats) override;

private:
    ia_ccat_frame_parameters mFrameParameters{};
    IPU7Aic* mAic;
};
}//cca
#endif //INTEL_CCA_H_
