/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * 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 "HidlCamera3-OutputUtils"
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
// Convenience macros for transitioning to the error state
#define SET_ERR(fmt, ...) states.setErrIntf.setErrorState(   \
    "%s: " fmt, __FUNCTION__,                         \
    ##__VA_ARGS__)

#include <inttypes.h>

#include <utils/Log.h>
#include <utils/SortedVector.h>
#include <utils/Trace.h>

#include <android/hardware/camera2/ICameraDeviceCallbacks.h>

#include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
#include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>

#include <camera/CameraUtils.h>
#include <camera_metadata_hidden.h>

#include "device3/hidl/HidlCamera3OutputUtils.h"
#include "device3/aidl/AidlCamera3OutputUtils.h"
#include "device3/Camera3Device.h"
#include "device3/Camera3OutputUtilsTemplated.h"

#include "system/camera_metadata.h"

using namespace android::camera3;
using namespace android::hardware::camera;

namespace android {
namespace camera3 {

void processOneCaptureResultLocked(
        HidlCaptureOutputStates& states,
        const hardware::camera::device::V3_2::CaptureResult& result,
        const hardware::hidl_vec<
                hardware::camera::device::V3_4::PhysicalCameraMetadata> &physicalCameraMetadata) {
    processOneCaptureResultLockedT<HidlCaptureOutputStates,
        hardware::camera::device::V3_2::CaptureResult,
        hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata>,
        hardware::hidl_vec<uint8_t>, ResultMetadataQueue,
        hardware::camera::device::V3_2::BufferStatus>(states, result, physicalCameraMetadata);
}

void notify(CaptureOutputStates& states,
        const hardware::camera::device::V3_2::NotifyMsg& msg) {

    using android::hardware::camera::device::V3_2::MsgType;
    using android::hardware::camera::device::V3_2::ErrorCode;

    ATRACE_CALL();
    camera_notify_msg m;
    switch (msg.type) {
        case MsgType::ERROR:
            m.type = CAMERA_MSG_ERROR;
            m.message.error.frame_number = msg.msg.error.frameNumber;
            if (msg.msg.error.errorStreamId >= 0) {
                sp<Camera3StreamInterface> stream =
                        states.outputStreams.get(msg.msg.error.errorStreamId);
                if (stream == nullptr) {
                    ALOGE("%s: Frame %d: Invalid error stream id %d", __FUNCTION__,
                            m.message.error.frame_number, msg.msg.error.errorStreamId);
                    return;
                }
                m.message.error.error_stream = stream->asHalStream();
            } else {
                m.message.error.error_stream = nullptr;
            }
            switch (msg.msg.error.errorCode) {
                case ErrorCode::ERROR_DEVICE:
                    m.message.error.error_code = CAMERA_MSG_ERROR_DEVICE;
                    break;
                case ErrorCode::ERROR_REQUEST:
                    m.message.error.error_code = CAMERA_MSG_ERROR_REQUEST;
                    break;
                case ErrorCode::ERROR_RESULT:
                    m.message.error.error_code = CAMERA_MSG_ERROR_RESULT;
                    break;
                case ErrorCode::ERROR_BUFFER:
                    m.message.error.error_code = CAMERA_MSG_ERROR_BUFFER;
                    break;
            }
            break;
        case MsgType::SHUTTER:
            m.type = CAMERA_MSG_SHUTTER;
            m.message.shutter.frame_number = msg.msg.shutter.frameNumber;
            m.message.shutter.timestamp = msg.msg.shutter.timestamp;
            m.message.shutter.readout_timestamp_valid = false;
            m.message.shutter.readout_timestamp = 0LL;
            break;
    }
    notify(states, &m);
}

static void convertToAidl(
        const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& hidlBufReqs,
        std::vector<aidl::android::hardware::camera::device::BufferRequest> &aidlBufReqs) {
    size_t i = 0;
    aidlBufReqs.resize(hidlBufReqs.size());
    for (const auto &hidlBufReq : hidlBufReqs) {
        aidlBufReqs[i].streamId = hidlBufReq.streamId;
        aidlBufReqs[i].numBuffersRequested = hidlBufReq.numBuffersRequested;
        i++;
    }
}

static hardware::camera::device::V3_5::StreamBufferRequestError
convertToHidl(aidl::android::hardware::camera::device::StreamBufferRequestError aError) {
    using AError = aidl::android::hardware::camera::device::StreamBufferRequestError;
    using HError = hardware::camera::device::V3_5::StreamBufferRequestError;

    switch(aError) {
        case AError::NO_BUFFER_AVAILABLE:
            return HError::NO_BUFFER_AVAILABLE;
        case AError::MAX_BUFFER_EXCEEDED:
            return HError::MAX_BUFFER_EXCEEDED;
        case AError::STREAM_DISCONNECTED:
            return HError::STREAM_DISCONNECTED;
        default:
            return HError::UNKNOWN_ERROR;
    }
}

static hardware::camera::device::V3_5::BufferRequestStatus
convertToHidl(const aidl::android::hardware::camera::device::BufferRequestStatus &aBufStatus) {
    using AStatus = aidl::android::hardware::camera::device::BufferRequestStatus;
    using HStatus = hardware::camera::device::V3_5::BufferRequestStatus;
    switch (aBufStatus) {
        case AStatus::OK:
            return HStatus::OK;
        case AStatus::FAILED_PARTIAL:
            return HStatus::FAILED_PARTIAL;
        case AStatus::FAILED_CONFIGURING:
            return HStatus::FAILED_CONFIGURING;
        case AStatus::FAILED_ILLEGAL_ARGUMENTS:
            return HStatus::FAILED_ILLEGAL_ARGUMENTS;
        case AStatus::FAILED_UNKNOWN:
            return HStatus::FAILED_UNKNOWN;
    }
    return HStatus::FAILED_UNKNOWN;
}

static hardware::camera::device::V3_2::BufferStatus
convertToHidl(const aidl::android::hardware::camera::device::BufferStatus &aBufStatus) {
    using AStatus = aidl::android::hardware::camera::device::BufferStatus;
    using HStatus = hardware::camera::device::V3_2::BufferStatus;
    switch (aBufStatus) {
        case AStatus::OK:
            return HStatus::OK;
        case AStatus::ERROR:
            return HStatus::ERROR;
    }
    return HStatus::ERROR;
}

static native_handle_t *convertToHidl(const aidl::android::hardware::common::NativeHandle &ah,
        std::vector<native_handle_t *> &handlesCreated) {
    if (isHandleNull(ah)) {
        return nullptr;
    }
    native_handle_t *nh = makeFromAidl(ah);
    handlesCreated.emplace_back(nh);
    return nh;
}

static void convertToHidl(
        const std::vector<aidl::android::hardware::camera::device::StreamBuffer> &aBuffers,
        hardware::camera::device::V3_5::StreamBuffersVal &hBuffersVal,
        std::vector<native_handle_t *> &handlesCreated) {
    using HStreamBuffer = hardware::camera::device::V3_2::StreamBuffer;
    hardware::hidl_vec<HStreamBuffer> tmpBuffers(aBuffers.size());
    size_t i = 0;
    for (const auto &aBuf : aBuffers) {
        tmpBuffers[i].status = convertToHidl(aBuf.status);
        tmpBuffers[i].streamId = aBuf.streamId;
        tmpBuffers[i].bufferId = aBuf.bufferId;
        tmpBuffers[i].buffer = convertToHidl(aBuf.buffer, handlesCreated);
        tmpBuffers[i].acquireFence = convertToHidl(aBuf.acquireFence, handlesCreated);
        tmpBuffers[i].releaseFence = convertToHidl(aBuf.releaseFence, handlesCreated);
        i++;
    }
    hBuffersVal.buffers(std::move(tmpBuffers));
}

static void convertToHidl(
        const std::vector<aidl::android::hardware::camera::device::StreamBufferRet> &aidlBufRets,
        hardware::hidl_vec<hardware::camera::device::V3_5::StreamBufferRet> &hidlBufRets,
        std::vector<native_handle_t *> &handlesCreated) {
    size_t i = 0;
    using Tag = aidl::android::hardware::camera::device::StreamBuffersVal::Tag;
    hidlBufRets.resize(aidlBufRets.size());
    for (const auto &aidlBufRet : aidlBufRets) {
        auto &hidlBufRet = hidlBufRets[i];
        hidlBufRet.streamId = aidlBufRet.streamId;
        switch(aidlBufRet.val.getTag()) {
          case Tag::error:
              hidlBufRet.val.error(convertToHidl(aidlBufRet.val.get<Tag::error>()));
              break;
          case Tag::buffers:
              convertToHidl(aidlBufRet.val.get<Tag::buffers>(), hidlBufRet.val, handlesCreated);
              break;
        }
        i++;
    }
}

// The buffers requested through this call are not tied to any CaptureRequest in
// particular. They may used by the hal for a particular frame's output buffer
// or for its internal use as well. In the case that the hal does use any buffer
// from the requested list here, for a particular frame's output buffer, the
// buffer will be returned with the processCaptureResult call corresponding to
// the frame. The other buffers will be returned through returnStreamBuffers.
// The buffers returned via returnStreamBuffers will not have a valid
// timestamp(0) and will be dropped by the bufferqueue.
void requestStreamBuffers(RequestBufferStates& states,
        const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
        hardware::camera::device::V3_5::ICameraDeviceCallback::requestStreamBuffers_cb _hidl_cb) {
   using android::hardware::camera::device::V3_2::BufferStatus;
    using android::hardware::camera::device::V3_2::StreamBuffer;
    using android::hardware::camera::device::V3_5::BufferRequestStatus;
    using android::hardware::camera::device::V3_5::StreamBufferRet;
    using android::hardware::camera::device::V3_5::StreamBufferRequestError;
    std::vector<aidl::android::hardware::camera::device::BufferRequest> aidlBufReqs;
    hardware::hidl_vec<hardware::camera::device::V3_5::StreamBufferRet> hidlBufRets;
    convertToAidl(bufReqs, aidlBufReqs);
    std::vector<::aidl::android::hardware::camera::device::StreamBufferRet> aidlBufRets;
    ::aidl::android::hardware::camera::device::BufferRequestStatus aidlBufRetStatus;

    requestStreamBuffers(states, aidlBufReqs, &aidlBufRets, &aidlBufRetStatus);
    std::vector<native_handle_t *> handlesCreated;
    convertToHidl(aidlBufRets, hidlBufRets, handlesCreated);
    _hidl_cb(convertToHidl(aidlBufRetStatus), hidlBufRets);
    Camera3Device::cleanupNativeHandles(&handlesCreated);
}

void returnStreamBuffers(ReturnBufferStates& states,
        const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
    returnStreamBuffersT(states, buffers);
}

} // camera3
} // namespace android
