/*
 * Copyright (C) 2017-2019 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 "ControlUnit"

#include "LogHelper.h"
#include "PerformanceTraces.h"
#include "ControlUnit.h"
#include "IPU3CameraHw.h"
#include "CaptureUnit.h"
#include "ImguUnit.h"
#include "CameraStream.h"
#include "IPU3CapturedStatistics.h"
#include "IPU3CameraCapInfo.h"
#include "CameraMetadataHelper.h"
#include "PlatformData.h"
#include "ProcUnitSettings.h"
#include "LensHw.h"
#include "SettingsProcessor.h"
#include "Metadata.h"
#include "AAARunner.h"

namespace cros {
namespace intel {

ControlUnit::ControlUnit(ImguUnit *thePU,
                         CaptureUnit *theCU,
                         int cameraId,
                         IStreamConfigProvider &aStreamCfgProv,
                         FaceEngine* faceEngine) :
        mRequestStatePool("CtrlReqState"),
        mCaptureUnitSettingsPool("CapUSettings"),
        mProcUnitSettingsPool("ProcUSettings"),
        mLatestStatistics(nullptr),
        mLatestRequestId(-1),
        mImguUnit(thePU),
        mCaptureUnit(theCU),
        m3aWrapper(nullptr),
        mCameraId(cameraId),
        mErrCb(nullptr),
        mCameraThread("CtrlUThread"),
        mBaseIso(100),
        mStreamCfgProv(aStreamCfgProv),
        mSettingsProcessor(nullptr),
        mMetadata(nullptr),
        m3ARunner(nullptr),
        mLensController(nullptr),
        mFaceEngine(faceEngine)
{
}

status_t
ControlUnit::init()
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL1, LOG_TAG);

    if (!mCameraThread.Start()) {
        LOGE("Camera thread failed to start");
        return UNKNOWN_ERROR;
    }

    const IPU3CameraCapInfo *cap = getIPU3CameraCapInfo(mCameraId);
    CheckError(!cap, UNKNOWN_ERROR, "Not enough information for getting NVM data");
    CheckError(cap->sensorType() != SENSOR_TYPE_RAW, UNKNOWN_ERROR, "SoC camera 3A control missing");

    m3aWrapper = new Intel3aPlus(mCameraId);
    m3aWrapper->enableAiqdDataSave(true);
    status_t status = m3aWrapper->initAIQ(MAX_STATISTICS_WIDTH,
                                          MAX_STATISTICS_HEIGHT,
                                          cap->getNvmData(),
                                          cap->getSensorName());
    CheckError(status != NO_ERROR, UNKNOWN_ERROR, "Error initializing 3A control");

    mSettingsProcessor = new SettingsProcessor(mCameraId, m3aWrapper, mStreamCfgProv);
    mSettingsProcessor->init();

    mMetadata = new Metadata(mCameraId, m3aWrapper);
    status = mMetadata->init();

    mCaptureUnit->setSettingsProcessor(mSettingsProcessor);

    /*
     * init the pools of Request State structs and CaptureUnit settings
     * and Processing Unit Settings
     */
    mRequestStatePool.init(MAX_REQUEST_IN_PROCESS_NUM, RequestCtrlState::reset);
    mCaptureUnitSettingsPool.init(SETTINGS_POOL_SIZE + 2);
    mProcUnitSettingsPool.init(SETTINGS_POOL_SIZE, ProcUnitSettings::reset);

    /*
     * Retrieve the Lens Controller interface from Capture Unit
     */
    LensHw *lensController = mCaptureUnit->getLensControlInterface();

    mSettingsHistory.clear();

    /* Set ISO map support */
    bool supportIsoMap = cap->getSupportIsoMap();
    m3aWrapper->setSupportIsoMap(supportIsoMap);

    m3ARunner = new AAARunner(mCameraId, m3aWrapper, mSettingsProcessor, lensController);

    /* Set digi gain support */
    bool supportDigiGain = cap->digiGainOnSensor();
    status = m3ARunner->init(supportDigiGain);

    status = allocateLscResults();
    if (CC_UNLIKELY(status != OK)) {
        LOGE("Failed to allocate LSC results");
        return NO_MEMORY;
    }

    return status;
}


/**
 * allocateLscResults
 *
 * Allocates the size of the LSC tables used as part of the AIQ results
 * that the 3A algorithms produce.
 * This allocation is done dynamically since it depends on the sensor.
 *
 * Since cmc is read here, base_iso is stored in this function also.
 *
 * The memory will be freed by the AiqResult destructor.
 *
 */
status_t ControlUnit::allocateLscResults()
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL1, LOG_TAG);
    status_t status = OK;
    std::shared_ptr<CaptureUnitSettings> capSettings = nullptr;
    ia_binary_data cpfData;
    ia_cmc_t *cmcData = nullptr;

    PlatformData::getCpfAndCmc(cpfData, &cmcData, nullptr, mCameraId);
    if (!cmcData) {
        LOGE("No CMC data available for sensor. fix the CPF file!");
        return UNKNOWN_ERROR;
    }

    if (cmcData && cmcData->cmc_sensitivity)
        mBaseIso = cmcData->cmc_sensitivity->base_iso;
    else
        LOGW("Cannot get base iso from cmc");

    if (!cmcData || !cmcData->cmc_parsed_lens_shading.cmc_lens_shading) {
        LOGW("Lens shading grid not set in cmc");
        return BAD_VALUE;
    }

    int tableH = cmcData->cmc_parsed_lens_shading.cmc_lens_shading->grid_height;
    int tableW = cmcData->cmc_parsed_lens_shading.cmc_lens_shading->grid_width;
    int tableSize = tableW * tableH;
    if (tableSize == 0) {
        LOGE("Invalid LSC table tize: fix the CPF file!");
        return BAD_VALUE;
    }

    int poolSize = mCaptureUnitSettingsPool.availableItems();
    for (int i = 0; i < poolSize; i++) {
        mCaptureUnitSettingsPool.acquireItem(capSettings);
        status = capSettings->aiqResults.allocateLsc(tableSize);
        if (CC_UNLIKELY(status != OK)) {
            break; // error reported outside
        }
        capSettings->aiqResults.init();
        m3ARunner->initLsc(capSettings->aiqResults, tableSize);
    }

    if (status == OK)
        status = m3ARunner->allocateLscTable(tableSize);

    return status;
}

/**
 * reset
 *
 * This method is called by the SharedPoolItem when the item is recycled
 * At this stage we can cleanup before recycling the struct.
 * In this case we reset the TracingSP of the capture unit settings and buffers
 * to remove this reference. Other references may be still alive.
 */
void RequestCtrlState::reset(RequestCtrlState* me)
{
    if (CC_LIKELY(me != nullptr)) {
        me->captureSettings.reset();
        me->processingSettings.reset();
        me->captureBufs.rawBuffer.reset();
        me->captureBufs.rawNonScaledBuffer.reset();
        me->captureBufs.lastRawNonScaledBuffer.reset();
        DELETE_ARRAY_AND_NULLIFY(me->rGammaLut);
        DELETE_ARRAY_AND_NULLIFY(me->gGammaLut);
        DELETE_ARRAY_AND_NULLIFY(me->bGammaLut);
    } else {
        LOGE("Trying to reset a null CtrlState structure !! - BUG ");
    }
}

void RequestCtrlState::init(Camera3Request *req)
{
    request = req;
    aiqInputParams.init();
    if (CC_LIKELY(captureSettings)) {
        captureSettings->aiqResults.init();
        captureSettings->aiqResults.requestId = req->getId();
        captureSettings->afRegion.init(0);
        captureSettings->aeRegion.init(0);
        captureSettings->makernote.data = nullptr;
        captureSettings->makernote.size = 0;
    } else {
        LOGE(" Failed to init Ctrl State struct: no capture settings!! - BUG");
        return;
    }
    if (CC_LIKELY(processingSettings.get() != nullptr)) {
        processingSettings->captureSettings = captureSettings;
        processingSettings->request = req;
    } else {
        LOGE(" Failed to init Ctrl State: no processing settings!! - BUG");
        return;
    }
    afState = ALGORITHM_NOT_CONFIG;
    aeState = ALGORITHM_NOT_CONFIG;
    awbState = ALGORITHM_NOT_CONFIG;
    ctrlUnitResult = request->getPartialResultBuffer(CONTROL_UNIT_PARTIAL_RESULT);
    statsArrived = false;
    framesArrived = 0;
    shutterDone = false;
    blackLevelOff = false;
    intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
    aaaControls.ae.aeMode =  ANDROID_CONTROL_AE_MODE_ON;
    aaaControls.af.afMode =  ANDROID_CONTROL_AF_MODE_AUTO;
    aaaControls.af.afTrigger =  ANDROID_CONTROL_AF_TRIGGER_IDLE;
    aaaControls.awb.awbMode =  ANDROID_CONTROL_AWB_MODE_AUTO;
    aaaControls.controlMode =  ANDROID_CONTROL_MODE_AUTO;

    tonemapContrastCurve = false;
    rGammaLut = nullptr;
    gGammaLut = nullptr;
    bGammaLut = nullptr;
    rGammaLutSize = 0;
    gGammaLutSize = 0;
    bGammaLutSize = 0;

    if (CC_UNLIKELY(ctrlUnitResult == nullptr)) {
        LOGE("no partial result buffer - BUG");
        return;
    }

    /**
     * Apparently we need to have this tags in the results
     */
    const android::CameraMetadata* settings = request->getSettings();

    if (CC_UNLIKELY(settings == nullptr)) {
        LOGE("no settings in request - BUG");
        return;
    }

    camera_metadata_ro_entry entry;
    entry = settings->find(ANDROID_REQUEST_ID);
    if (entry.count == 1) {
        ctrlUnitResult->update(ANDROID_REQUEST_ID, entry.data.i32,
                entry.count);
    }
    int64_t id = captureSettings->aiqResults.requestId;
    ctrlUnitResult->update(ANDROID_SYNC_FRAME_NUMBER,
                          &id, 1);

    entry = settings->find(ANDROID_CONTROL_CAPTURE_INTENT);
    if (entry.count == 1) {
        intent = entry.data.u8[0];
    }

    ctrlUnitResult->update(ANDROID_CONTROL_CAPTURE_INTENT, entry.data.u8,
                                                           entry.count);
    entry = settings->find(ANDROID_CONTROL_MODE);
    if (entry.count == 1) {
        aaaControls.controlMode = entry.data.u8[0];
        ctrlUnitResult->update(ANDROID_CONTROL_MODE, entry.data.u8, entry.count);
    }

    entry = settings->find(ANDROID_CONTROL_AE_MODE);
    if (entry.count == 1) {
        aaaControls.ae.aeMode = entry.data.u8[0];
        ctrlUnitResult->update(ANDROID_CONTROL_AE_MODE, entry.data.u8, entry.count);
    }
}

ControlUnit::~ControlUnit()
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL1, LOG_TAG);

    mLatestStatistics = nullptr;
    mSettingsHistory.clear();

    mCameraThread.Stop();

    if (mSettingsProcessor) {
        delete mSettingsProcessor;
        mSettingsProcessor = nullptr;
    }

    if (m3aWrapper) {
        m3aWrapper->deinit();
        delete m3aWrapper;
        m3aWrapper = nullptr;
    }

    delete mMetadata;
    mMetadata = nullptr;

    delete m3ARunner;
    m3ARunner = nullptr;
}

void ControlUnit::registerErrorCallback(IErrorCallback *errCb)
{
    LOG1("@%s, errCb:%p", __FUNCTION__, errCb);
    mErrCb = errCb;
}

status_t
ControlUnit::configStreamsDone(bool configChanged)
{
    LOG1("@%s: config changed: %d", __FUNCTION__, configChanged);

    if (configChanged) {
        mLatestRequestId = -1;
        mPendingRequests.clear();
        mWaitingForCapture.clear();
        mSettingsHistory.clear();
    }

    return NO_ERROR;
}

/**
 * acquireRequestStateStruct
 *
 * acquire a free request control state structure.
 * Since this structure contains also a capture settings item that are also
 * stored in a pool we need to acquire one of those as well.
 *
 */
status_t
ControlUnit::acquireRequestStateStruct(std::shared_ptr<RequestCtrlState>& state)
{
    status_t status = NO_ERROR;
    status = mRequestStatePool.acquireItem(state);
    if (status != NO_ERROR) {
        LOGE("Failed to acquire free request state struct - BUG");
        /*
         * This should not happen since AAL is holding clients to send more
         * requests than we can take
         */
        return UNKNOWN_ERROR;
    }

    status = mCaptureUnitSettingsPool.acquireItem(state->captureSettings);
    if (status != NO_ERROR) {
        LOGE("Failed to acquire free CapU settings  struct - BUG");
        /*
         * This should not happen since AAL is holding clients to send more
         * requests than we can take
         */
        return UNKNOWN_ERROR;
    }

    // set a unique ID for the settings
    state->captureSettings->settingsIdentifier = systemTime();

    status = mProcUnitSettingsPool.acquireItem(state->processingSettings);
    if (status != NO_ERROR) {
        LOGE("Failed to acquire free ProcU settings  struct - BUG");
        /*
         * This should not happen since AAL is holding clients to send more
         * requests than we can take
         */
        return UNKNOWN_ERROR;
    }
    return OK;
}

/**
 * processRequest
 *
 * Acquire the control structure to keep the state of the request in the control
 * unit and send the message to be handled in the internal message thread.
 */
status_t
ControlUnit::processRequest(Camera3Request* request)
{
    status_t status = NO_ERROR;
    std::shared_ptr<RequestCtrlState> state;
    LOG2("@%s: id %d", __FUNCTION__, request->getId());

    status = acquireRequestStateStruct(state);
    if (CC_UNLIKELY(status != OK) || CC_UNLIKELY(state.get() == nullptr)) {
        return status;  // error log already done in the helper method
    }

    state->init(request);

    base::Callback<status_t()> closure =
            base::Bind(&ControlUnit::handleNewRequest, base::Unretained(this),
                       base::Passed(std::move(state)));
    mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
    return OK;
}

status_t ControlUnit::handleNewRequest(std::shared_ptr<RequestCtrlState> state)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);

    status_t status = NO_ERROR;
    std::shared_ptr<RequestCtrlState> reqState = state;

    /**
     * PHASE 1: Process the settings
     * In this phase we analyze the request's metadata settings and convert them
     * into either:
     *  - input parameters for 3A algorithms
     *  - parameters used for SoC sensors
     *  - Capture Unit settings
     *  - Processing Unit settings
     */
    const android::CameraMetadata *reqSettings = reqState->request->getSettings();

    CheckAndCallbackError(reqSettings == nullptr, mErrCb, UNKNOWN_ERROR,
                          "@%s: no settings in request", __FUNCTION__);

    status = mSettingsProcessor->processRequestSettings(*reqSettings, *reqState);
    if (status != NO_ERROR) {
        LOGE("Could not process all settings, reporting request as invalid");
    }

    mPendingRequests.push_back(reqState);
    reqState = mPendingRequests[0];

    /**
     * PHASE2: Process for capture or Q or reprocessing
     * Use dummy stats if no stats is received.
     *
     * Use the latest valid stats for still capture,
     * it comes from video pipe (during still preview).
     *
     * Holding request if there is enough requests processing in CIO2
     * when has VIDEO pipe.
     */
    if ((mLatestRequestId > PENDING_REQUEST_FOR_AWB_CONVERGENCE &&
         mWaitingForCapture.size() < MAX_CIO2_PROCESSING_REQUEST_NUM) ||
        mLatestRequestId == -1 ||
        !mImguUnit->hasVideoPipe() ||
        (mLatestStatistics != nullptr &&
         mLatestRequestId == mLatestStatistics->id)) {
      mPendingRequests.erase(mPendingRequests.begin());

      status = processRequestForCapture(reqState, mLatestStatistics);
      CheckAndCallbackError(status != OK, mErrCb, status,
                            "@%s: Failed to process req %d for capture",
                            __FUNCTION__, reqState->request->getId());
    }

    return status;
}

/**
 * processRequestForCapture
 *
 * Run 3A algorithms and send the results to capture unit for capture
 *
 * This is the second phase in the request processing flow.
 *
 * The request settings have been processed in the first phase
 *
 * If this step is successful the request will be moved to the
 * mWaitingForCapture waiting for the pixel buffers.
 */
status_t
ControlUnit::processRequestForCapture(std::shared_ptr<RequestCtrlState> &reqState,
                                      std::shared_ptr<IPU3CapturedStatistics> &stats)
{
    status_t status = NO_ERROR;
    if (CC_UNLIKELY(reqState.get() == nullptr)) {
        LOGE("Invalid parameters passed- request not captured - BUG");
        return BAD_VALUE;
    }

    if (CC_UNLIKELY(reqState->captureSettings.get() == nullptr)) {
        LOGE("capture Settings not given - BUG");
        return BAD_VALUE;
    }

    /* Write the dump flag into capture settings, so that the PAL dump can be
     * done all the way down at PgParamAdaptor. For the time being, only dump
     * during jpeg captures.
     */
    reqState->processingSettings->dump =
            LogHelper::isDumpTypeEnable(CAMERA_DUMP_RAW) &&
            reqState->request->getBufferCountOfFormat(HAL_PIXEL_FORMAT_BLOB) > 0;
    // dump the PAL run from ISA also
    reqState->captureSettings->dump = reqState->processingSettings->dump;

    int reqId = reqState->request->getId();

    if (stats != nullptr) {
        prepareStats(*reqState, *stats.get());
        LOG2("%s, stats frame sequence %u", __FUNCTION__, stats->frameSequence);
    }

    bool forceUpdated = (mLatestRequestId < 0 ? true : false);
    status = m3ARunner->run2A(*reqState, forceUpdated);
    if (status != NO_ERROR) {
       LOGE("Error in running run2AandCapture for request %d", reqId);
       return status;
    }

    mMetadata->writeLSCMetadata(reqState);

    m3ARunner->runAf(*reqState);

    // Latest results are saved for the next frame calculation if we do not
    // find the correct results.
    // TODO: Remove this once we fix the request flow so we can use the results
    // from the request at prepareStats
    m3aWrapper->deepCopyAiqResults(m3ARunner->getLatestResults(),
                                   reqState->captureSettings->aiqResults,
                                   true);
    m3ARunner->updateInputParams(reqState->aiqInputParams);

    status = mCaptureUnit->doCapture(reqState->request,
                                     reqState->captureSettings);
    if (CC_UNLIKELY(status != NO_ERROR)) {
        LOGE("Failed to issue capture request for id %d", reqId);
    }
    /**
     * Move the request to the vector mWaitingForCapture
     */
    mWaitingForCapture.insert(std::make_pair(reqId, reqState));
    mLatestRequestId = reqId;

    /*
     * Store the settings in the settings history if we expect stats to be in
     * use. This is only in case the control mode is different than
     * ANDROID_CONTROL_MODE_OFF_KEEP_STATE
     * WA - HAL runs out of capture settings in ANDROID_CONTROL_MODE_OFF,
     * so history is not udated for it. TODO fix later so that 3A runs in
     * background without actually applying the settings.
     */
    if (reqState->aaaControls.controlMode != ANDROID_CONTROL_MODE_OFF_KEEP_STATE &&
        reqState->aaaControls.controlMode != ANDROID_CONTROL_MODE_OFF) {
        // Keep the size of the history fixed
        if (mSettingsHistory.size() >= MAX_SETTINGS_HISTORY_SIZE) {
            LOGP("%s delete one hold for %p in mCaptureUnitSettingsPool",
                 __FUNCTION__, mSettingsHistory.begin()->get());
            mSettingsHistory.erase(mSettingsHistory.begin());
        }

        mSettingsHistory.push_back(reqState->captureSettings);
        LOGP("%s add one hold for %p in mCaptureUnitSettingsPool",
             __FUNCTION__, reqState->captureSettings.get());
    }

    int jpegBufCount = reqState->request->getBufferCountOfFormat(HAL_PIXEL_FORMAT_BLOB);
    int implDefinedBufCount = reqState->request->getBufferCountOfFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
    int yuv888BufCount = reqState->request->getBufferCountOfFormat(HAL_PIXEL_FORMAT_YCbCr_420_888);
    LOG2("@%s jpegs:%d impl defined:%d yuv888:%d inputbufs:%d req id %d",
         __FUNCTION__,
         jpegBufCount,
         implDefinedBufCount,
         yuv888BufCount,
         (reqState->request->hasInputBuf() ? 1 : 0),
         reqState->request->getId());
    if (jpegBufCount > 0) {
        // NOTE: Makernote should be get after isp_bxt_run()
        // NOTE: makernote.data deleted in JpegEncodeTask::handleMakernote()
        const unsigned mknSize = MAKERNOTE_SECTION1_SIZE + MAKERNOTE_SECTION2_SIZE;
        MakernoteData mkn = {nullptr, mknSize};
        mkn.data = new char[mknSize];
        m3aWrapper->getMakerNote(ia_mkn_trg_section_2, mkn);

        reqState->captureSettings->makernote = mkn;

    } else {
        // No JPEG buffers in request. Reset MKN info, just in case.
        reqState->captureSettings->makernote.data = nullptr;
        reqState->captureSettings->makernote.size = 0;
    }

    return status;
}

status_t ControlUnit::handleNewImage(MessageNewImage msg)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);
    int reqId = msg.requestId;

    std::map<int, std::shared_ptr<RequestCtrlState>>::iterator it =
                                    mWaitingForCapture.find(reqId);
    CheckAndCallbackError(it == mWaitingForCapture.end(), mErrCb, UNKNOWN_ERROR,
                          "@%s, Unexpected new image received %d", __FUNCTION__, reqId);

    std::shared_ptr<RequestCtrlState> reqState = it->second;
    CheckAndCallbackError(reqState == nullptr, mErrCb, UNKNOWN_ERROR,
                          "@%s, State for request Id = %d is nullptr", __FUNCTION__, reqId);

    /*
     * Send the buffer. See complete processing to understand
     * how we do the hold up.
     */
    reqState->captureBufs.rawBuffer = nullptr;
    reqState->captureBufs.rawNonScaledBuffer = nullptr;
    reqState->captureBufs.lastRawNonScaledBuffer = nullptr;

    reqState->framesArrived++;

    CheckAndCallbackError(msg.type != CAPTURE_EVENT_RAW_BAYER, mErrCb, UNKNOWN_ERROR,
                          "@%s, Unknown capture buffer type in request %d", __FUNCTION__, reqId);

    reqState->captureBufs.rawNonScaledBuffer = msg.rawBuffer;
    reqState->captureBufs.lastRawNonScaledBuffer = msg.lastRawBuffer;

    status_t status = completeProcessing(reqState);
    CheckAndCallbackError(status != OK, mErrCb, status,
                          "@%s, Cannot complete the buffer processing", __FUNCTION__);

    return OK;
}

status_t ControlUnit::handleNewStat(MessageStats msg)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);
    status_t status = NO_ERROR;
    std::shared_ptr<IPU3CapturedStatistics> stats = msg.stats;
    int statsId = 0;
    if (stats.get() != nullptr) {
        statsId = stats->id;

        // Still pipe has no stats output and data is invalid
        // so here only valid data are saved.
        if (stats->rgbsGridArray[0] && stats->rgbsGridArray[0]->grid_width)
            mLatestStatistics = stats;
    }

    if (mPendingRequests.empty()) {
        return status;
    }

    // If enough requests are processing, don't need to process next request.
    if (mWaitingForCapture.size() >= MAX_CIO2_PROCESSING_REQUEST_NUM) {
        return NO_ERROR;
    }

    size_t reqCount = 1;
    if (statsId == mLatestRequestId && mLatestRequestId >= PENDING_REQUEST_FOR_AWB_CONVERGENCE) {
        // The 0 ~ PENDING_REQUEST_FOR_AWB_CONVERGENCE request will run with new statistics to speed
        // AWB converging process. Otherwise, queue all pending requests to CIO2.
        reqCount = MAX_CIO2_PROCESSING_REQUEST_NUM;
    }

    // Process request
    for (size_t i = 0; i < reqCount && !mPendingRequests.empty(); i++) {
        std::shared_ptr<RequestCtrlState> reqState = mPendingRequests[0];
        mPendingRequests.erase(mPendingRequests.begin());

        CheckAndCallbackError((!reqState || reqState->request == nullptr), mErrCb,
                              UNKNOWN_ERROR, "@%s, reqState is nullptr, find BUG!", __FUNCTION__);

        LOG2("@%s: process reqState %d", __FUNCTION__, reqState->request->getId());

        status = processRequestForCapture(reqState, mLatestStatistics);
        CheckAndCallbackError(status != OK, mErrCb, status,
                              "@%s: Failed to process request %d for capture",
                               __FUNCTION__, reqState->request->getId());
    }

    return status;
}

/**
 * completeProcessing
 *
 * Forward the pixel buffer to the Processing Unit to complete the processing.
 * If all the buffers from Capture Unit have arrived then:
 * - it updates the metadata
 * - it removes the request from the vector mWaitingForCapture.
 *
 * The metadata update is now transferred to the ProcessingUnit.
 * This is done only on arrival of the last pixel data buffer. ControlUnit still
 * keeps the state, so it is responsible for triggering the update.
 */
status_t
ControlUnit::completeProcessing(std::shared_ptr<RequestCtrlState> &reqState)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);
    int reqId = reqState->captureSettings->aiqResults.requestId;
    bool updateMeta = false;

    LOG2("complete processing req %d frames arrived %d",
             reqId, reqState->framesArrived);

    // We do this only once per request when the first buffer arrives
    if (reqState->framesArrived == 1) {
        mMetadata->writeAwbMetadata(*reqState);
        mMetadata->writeSensorMetadata(*reqState);
        mMetadata->writePAMetadata(*reqState);
        mMetadata->writeJpegMetadata(*reqState);
        mMetadata->writeMiscMetadata(*reqState);
        mMetadata->writeLensMetadata(*reqState);
        mMetadata->fillTonemapCurve(*reqState);

        int64_t rollingShutterSkew = mCaptureUnit->getRollingShutterSkew();
        //# ANDROID_METADATA_Dynamic android.sensor.rollingShutterSkew done
        reqState->ctrlUnitResult->update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
                                         &rollingShutterSkew, 1);

        uint8_t pipelineDepth = mCaptureUnit->getPipelineDepth();
        //# ANDROID_METADATA_Dynamic android.request.pipelineDepth done
        reqState->ctrlUnitResult->update(ANDROID_REQUEST_PIPELINE_DEPTH,
                                         &pipelineDepth, 1);
    }

    updateMeta = true;

    mWaitingForCapture.erase(reqId);

    if (CC_LIKELY((reqState->request != nullptr) &&
                  (reqState->captureSettings.get() != nullptr))) {
        LOG2("%s: completing buffer %d for request %d",
                __FUNCTION__,
                reqState->framesArrived,
                reqId);

        /* TODO: cleanup
         * This struct copy from state is only needed for JPEG creation.
         * Ideally we should directly write inside members of processingSettings
         * whatever settings are needed for Processing Unit.
         * This should be moved to any of the processXXXSettings.
         */
        reqState->processingSettings->android3Actrl = reqState->aaaControls;

        mImguUnit->completeRequest(reqState->processingSettings,
                                         reqState->captureBufs,
                                         updateMeta);
    } else {
        LOGE("request or captureSetting is nullptr - Fix the bug!");
        return UNKNOWN_ERROR;
    }

    return NO_ERROR;
}

status_t ControlUnit::handleNewShutter(MessageShutter msg)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);
    std::shared_ptr<RequestCtrlState> reqState = nullptr;
    int reqId = msg.requestId;

    std::map<int, std::shared_ptr<RequestCtrlState>>::iterator it =
                                    mWaitingForCapture.find(reqId);
    if (it == mWaitingForCapture.end()) {
        LOGE("Unexpected shutter event received for request %d - Fix the bug", reqId);
        return UNKNOWN_ERROR;
    }
    reqState = it->second;
    if (CC_UNLIKELY(reqState.get() == nullptr || reqState->captureSettings.get() == nullptr)) {
        LOGE("No valid state or settings for request Id = %d"
             "- Fix the bug!", reqId);
        return UNKNOWN_ERROR;
    }

    /* flash state - hack, should know from frame whether it fired */
    const android::CameraMetadata* metaData = reqState->request->getSettings();
    if (metaData == nullptr) {
        LOGE("Metadata should not be nullptr. Fix the bug!");
        return UNKNOWN_ERROR;
    }

    uint8_t flashState = ANDROID_FLASH_STATE_UNAVAILABLE;

    //# ANDROID_METADATA_Dynamic android.flash.state done
    reqState->ctrlUnitResult->update(ANDROID_FLASH_STATE, &flashState, 1);

    int64_t ts = msg.tv_sec * 1000000000; // seconds to nanoseconds
    ts += msg.tv_usec * 1000; // microseconds to nanoseconds
    //use request setting timestamp when reprocess
    if (reqState->request->hasInputBuf()){
        camera_metadata_ro_entry entry;
        entry = metaData->find(ANDROID_SENSOR_TIMESTAMP);
        if (entry.count == 1) {
            ts = entry.data.i64[0];
        }
    }
    //# ANDROID_METADATA_Dynamic android.sensor.timestamp done
    reqState->ctrlUnitResult->update(ANDROID_SENSOR_TIMESTAMP, &ts, 1);
    reqState->request->mCallback->shutterDone(reqState->request, ts);
    reqState->shutterDone = true;
    reqState->captureSettings->timestamp = ts;

    return NO_ERROR;
}

status_t ControlUnit::handleNewSensorDescriptor(MessageSensorMode msg)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL1, LOG_TAG);
    mMetadata->FillSensorDescriptor(msg);
    return mSettingsProcessor->handleNewSensorDescriptor(msg);
}

status_t
ControlUnit::flush(void)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);
    status_t status = NO_ERROR;
    base::Callback<status_t()> closure =
            base::Bind(&ControlUnit::handleFlush, base::Unretained(this));
    mCameraThread.PostTaskSync<status_t>(FROM_HERE, closure, &status);
    return status;
}

status_t ControlUnit::handleFlush(void)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);

    mWaitingForCapture.clear();
    mPendingRequests.clear();
    mSettingsHistory.clear();

    return NO_ERROR;
}

bool
ControlUnit::notifyCaptureEvent(CaptureMessage *captureMsg)
{
    HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2, LOG_TAG);

    if (captureMsg == nullptr) {
        return false;
    }

    if (captureMsg->id == CAPTURE_MESSAGE_ID_ERROR) {
        // handle capture error
        return true;
    }

    switch (captureMsg->data.event.type) {
        case CAPTURE_EVENT_RAW_BAYER:
        {
            MessageNewImage msg;
            msg.type = CAPTURE_EVENT_RAW_BAYER;
            msg.requestId = captureMsg->data.event.reqId;
            msg.rawBuffer = captureMsg->data.event.pixelBuffer;
            msg.lastRawBuffer = captureMsg->data.event.lastPixelBuffer;
            base::Callback<status_t()> closure =
                    base::Bind(&ControlUnit::handleNewImage,
                               base::Unretained(this),
                               base::Passed(std::move(msg)));
            mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
            break;
        }
        case CAPTURE_EVENT_NEW_SENSOR_DESCRIPTOR:
        {
            MessageSensorMode msg;
            msg.exposureDesc = captureMsg->data.event.exposureDesc;
            msg.frameParams = captureMsg->data.event.frameParams;
            base::Callback<status_t()> closure =
                    base::Bind(&ControlUnit::handleNewSensorDescriptor,
                               base::Unretained(this),
                               base::Passed(std::move(msg)));
            mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
            break;
        }
        case CAPTURE_EVENT_2A_STATISTICS:
            if (CC_UNLIKELY(captureMsg->data.event.stats.get() == nullptr)) {
                LOGE("captureMsg->stats == nullptr");
                return false;
            } else {
                MessageStats msg;
                msg.stats = captureMsg->data.event.stats;
                base::Callback<status_t()> closure =
                        base::Bind(&ControlUnit::handleNewStat,
                                   base::Unretained(this),
                                   base::Passed(std::move(msg)));
                mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
            }
            break;
        case CAPTURE_EVENT_SHUTTER:
        {
            MessageShutter msg;
            msg.requestId = captureMsg->data.event.reqId;
            msg.tv_sec = captureMsg->data.event.timestamp.tv_sec;
            msg.tv_usec = captureMsg->data.event.timestamp.tv_usec;
            base::Callback<status_t()> closure =
                    base::Bind(&ControlUnit::handleNewShutter,
                               base::Unretained(this),
                               base::Passed(std::move(msg)));
            mCameraThread.PostTaskAsync<status_t>(FROM_HERE, closure);
            break;
        }
        case CAPTURE_EVENT_NEW_SOF:
        {
            std::lock_guard<std::mutex> l(mSofDataLock);
            if (mSofDataMap.size() >= MAX_SETTINGS_HISTORY_SIZE) {
                mSofDataMap.erase(mSofDataMap.begin());
            }
            mSofDataMap[captureMsg->data.event.sequence] =
                      captureMsg->data.event.timestamp.tv_sec * 1000000
                      + captureMsg->data.event.timestamp.tv_usec;
            LOG2("sof event sequence = %u", captureMsg->data.event.sequence);
            break;
        }
        default:
            LOGW("Unsupported Capture event ");
            break;
    }

    return true;
}

/**
 * prepareStats
 *
 * Prepares the ia_aiq_statistics_input_params struct before running 3A and then
 * it calls Intel3Aplus::setStatistics() to pass them to the 3A algorithms.
 *
 * The main preparation consist in finding the capture unit settings that were
 * in effect when the statistics where captured.
 *
 * The AIQ results in effect when the statistics were gathered are available in
 * the control unit
 * TODO: Current flow is not handling these results well. We may have completed
 * the request and the results are lost. We need to keep the capture settings
 * alive longer than the request state struct. This was done in Sofia.
 *
 * Alternatively once we have EmDa we can also use that.
 *
 * \param reqState [IN/OUT]: request to process
 * \param s [OUT]: structure holding the captured stats
 */
void ControlUnit::prepareStats(RequestCtrlState &reqState,
                               IPU3CapturedStatistics &s)
{
    status_t status = NO_ERROR;
    std::shared_ptr<CaptureUnitSettings> settingsInEffect = nullptr;
    LOG2(" %s: statistics from request %d used to process request %d",
        __FUNCTION__, s.id,
        reqState.request->getId());

    // Prepare the input parameters for the statistics
    ia_aiq_statistics_input_params* params = &s.aiqStatsInputParams;
    params->camera_orientation = ia_aiq_camera_orientation_unknown;

    params->external_histograms = nullptr;
    params->num_external_histograms = 0;

    settingsInEffect = findSettingsInEffect(params->frame_id);
    if (settingsInEffect.get()) {
        params->frame_ae_parameters = &settingsInEffect->aiqResults.aeResults;
        params->frame_af_parameters = &settingsInEffect->aiqResults.afResults;
        params->awb_results = &settingsInEffect->aiqResults.awbResults;
        params->frame_sa_parameters = &settingsInEffect->aiqResults.saResults;
        params->frame_pa_parameters = &settingsInEffect->aiqResults.paResults;
    } else {
        LOG1("preparing statistics from exp %lld that we do not track", params->frame_id);

        // default to latest results
        AiqResults& latestResults = m3ARunner->getLatestResults();
        params->frame_ae_parameters = &latestResults.aeResults;
        params->frame_af_parameters = &latestResults.afResults;
        params->awb_results = &latestResults.awbResults;
        params->frame_sa_parameters = &latestResults.saResults;
        params->frame_pa_parameters = &latestResults.paResults;
    }

    unsigned long long sofTimestamp = 0;
    {
    std::lock_guard<std::mutex> l(mSofDataLock);
    if (mSofDataMap.find(params->frame_id) != mSofDataMap.end()) {
        sofTimestamp = mSofDataMap.at(params->frame_id);
    } else {
        LOG2("frame timestamp %llu us, rolling shutter time %ld us", params->frame_timestamp,
              mCaptureUnit->getRollingShutterSkew() / 1000);
        sofTimestamp = params->frame_timestamp - mCaptureUnit->getRollingShutterSkew() / 1000;
    }
    }
    params->frame_timestamp = sofTimestamp
              - params->frame_ae_parameters->exposures[0].exposure->exposure_time_us;
    LOG2("frame expo start timestamp %lld, sequence %llu", params->frame_timestamp,
              params->frame_id);

    ia_face faces[MAX_FACES_DETECTABLE] = {};
    ia_face_state facesState;
    if (mFaceEngine && mFaceEngine->getMode() != FD_MODE_OFF) {
        facesState.num_faces = 0;
        facesState.faces = faces;
        int ret = mFaceEngine->getResult(&facesState);
        if (ret == OK && facesState.num_faces > 0) {
            params->faces = &facesState;
        } else {
            params->faces = nullptr;
        }
        LOG2("@%s, face number:%d", __FUNCTION__, facesState.num_faces);

        CVFaceEngineAbstractResult fdResult;
        ret = mFaceEngine->getResult(&fdResult);
        if (ret == OK) {
            mMetadata->writeFDMetadata(reqState, fdResult);
        }
    }

    /**
     * Pass stats to all 3A algorithms
     * Since at the moment we do not have separate events for AF and AA stats
     * there is no need to pass the stats per algorithm.
     * AF usually runs first, but not always. For that reason we pass the stats
     * to the AIQ algorithms here.
     */
    status = m3aWrapper->setStatistics(params);
    if (CC_UNLIKELY(status != OK)) {
        LOGW("Failed to set statistics for 3A iteration");
    }

    // algo's are ready to run
    reqState.afState = ALGORITHM_READY;
    reqState.aeState = ALGORITHM_READY;
    reqState.awbState = ALGORITHM_READY;
}

/**
 *
 * find the capture unit settings that were in effect for the frame with
 * exposure id (expId) was captured.
 *
 * Iterates through the vector settings history to find the settings marked as
 * in effect in an exposure id that is the same or bigger.
 *
 * It keeps the size of the settings history buffer limited.
 */
std::shared_ptr<CaptureUnitSettings> ControlUnit::findSettingsInEffect(uint64_t expId)
{
    std::shared_ptr<CaptureUnitSettings> settingsInEffect = nullptr;
    std::deque<std::shared_ptr<CaptureUnitSettings>>::iterator it;
    for (it = mSettingsHistory.begin(); it != mSettingsHistory.end(); ++it) {
        if ((*it)->inEffectFrom == expId) {
            // we found the exact settings
            settingsInEffect = *it;
            break;
        }
        if ((*it)->inEffectFrom > expId && it != mSettingsHistory.begin()) {
            // Pick the previous settings which have had effect already.
            // "it" is not the history begin so "it--" is safe.
            it--;
            settingsInEffect = *it;
            break;
        }
    }
    if (it == mSettingsHistory.end() && !mSettingsHistory.empty()) {
        LOG2("Could not find settings for expID %" PRIu64 " providing for %d", expId,
             mSettingsHistory[0]->inEffectFrom);
        settingsInEffect = mSettingsHistory[0];
    }

    return settingsInEffect;
}

} // namespace intel
} // namespace cros

