/*
**
** Copyright 2013, 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_NDEBUG 0
#define LOG_TAG "CameraRequest"
#include <utils/Log.h>
#include <utils/String16.h>

#include <camera/camera2/CaptureRequest.h>
#include <camera/StringUtils.h>

#include <binder/Parcel.h>
#include <gui/Flags.h>  // remove with WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
#include <gui/Surface.h>
#include <gui/view/Surface.h>

namespace android {
namespace hardware {
namespace camera2 {

// These must be in the .cpp (to avoid inlining)
CaptureRequest::CaptureRequest() = default;
CaptureRequest::~CaptureRequest() = default;
CaptureRequest::CaptureRequest(const CaptureRequest& rhs) = default;
CaptureRequest::CaptureRequest(CaptureRequest&& rhs) noexcept = default;


status_t CaptureRequest::readFromParcel(const android::Parcel* parcel) {
    if (parcel == NULL) {
        ALOGE("%s: Null parcel", __FUNCTION__);
        return BAD_VALUE;
    }

    mSurfaceList.clear();
    mStreamIdxList.clear();
    mSurfaceIdxList.clear();
    mPhysicalCameraSettings.clear();

    status_t err = OK;

    int32_t settingsCount;
    if ((err = parcel->readInt32(&settingsCount)) != OK) {
        ALOGE("%s: Failed to read the settings count from parcel: %d", __FUNCTION__, err);
        return err;
    }

    if (settingsCount <= 0) {
        ALOGE("%s: Settings count %d should always be positive!", __FUNCTION__, settingsCount);
        return BAD_VALUE;
    }

    for (int32_t i = 0; i < settingsCount; i++) {
        String16 id;
        if ((err = parcel->readString16(&id)) != OK) {
            ALOGE("%s: Failed to read camera id!", __FUNCTION__);
            return BAD_VALUE;
        }

        CameraMetadata settings;
        if ((err = settings.readFromParcel(parcel)) != OK) {
            ALOGE("%s: Failed to read metadata from parcel", __FUNCTION__);
            return err;
        }
        ALOGV("%s: Read metadata from parcel", __FUNCTION__);
        mPhysicalCameraSettings.push_back({toStdString(id), settings});
    }

    int isReprocess = 0;
    if ((err = parcel->readInt32(&isReprocess)) != OK) {
        ALOGE("%s: Failed to read reprocessing from parcel", __FUNCTION__);
        return err;
    }
    mIsReprocess = (isReprocess != 0);

    int32_t size;
    if ((err = parcel->readInt32(&size)) != OK) {
        ALOGE("%s: Failed to read surface list size from parcel", __FUNCTION__);
        return err;
    }
    ALOGV("%s: Read surface list size = %d", __FUNCTION__, size);

    // Do not distinguish null arrays from 0-sized arrays.
    for (int32_t i = 0; i < size; ++i) {
        // Parcel.writeParcelableArray
        std::optional<std::string> className;
        parcel->readUtf8FromUtf16(&className);
        ALOGV("%s: Read surface class = %s", __FUNCTION__,
              className.value_or("<null>").c_str());

        if (className == std::nullopt) {
            continue;
        }

        // Surface.writeToParcel
        view::Surface surfaceShim;
        if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
            ALOGE("%s: Failed to read output target Surface %d from parcel: %s (%d)",
                    __FUNCTION__, i, strerror(-err), err);
            return err;
        }

#if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
        sp<Surface> surface = surfaceShim.toSurface();
#else
        sp<Surface> surface;
        if (surfaceShim.graphicBufferProducer != NULL) {
            surface = sp<Surface>::make(surfaceShim.graphicBufferProducer);
        }
#endif
        mSurfaceList.push_back(surface);
    }

    int32_t streamSurfaceSize;
    if ((err = parcel->readInt32(&streamSurfaceSize)) != OK) {
        ALOGE("%s: Failed to read streamSurfaceSize from parcel", __FUNCTION__);
        return err;
    }

    if (streamSurfaceSize < 0) {
        ALOGE("%s: Bad streamSurfaceSize %d from parcel", __FUNCTION__, streamSurfaceSize);
        return BAD_VALUE;
    }

    for (int32_t i = 0; i < streamSurfaceSize; ++i) {
        int streamIdx;
        if ((err = parcel->readInt32(&streamIdx)) != OK) {
            ALOGE("%s: Failed to read stream index from parcel", __FUNCTION__);
            return err;
        }
        mStreamIdxList.push_back(streamIdx);

        int surfaceIdx;
        if ((err = parcel->readInt32(&surfaceIdx)) != OK) {
            ALOGE("%s: Failed to read surface index from parcel", __FUNCTION__);
            return err;
        }
        mSurfaceIdxList.push_back(surfaceIdx);
    }

    int32_t hasUserTag;
    if ((err = parcel->readInt32(&hasUserTag)) != OK) {
        ALOGE("%s: Failed to read user tag availability flag", __FUNCTION__);
        return BAD_VALUE;
    }
    if (hasUserTag) {
        String16 userTag;
        if ((err = parcel->readString16(&userTag)) != OK) {
            ALOGE("%s: Failed to read user tag!", __FUNCTION__);
            return BAD_VALUE;
        }
        mUserTag = toStdString(userTag);
    }

    return OK;
}

status_t CaptureRequest::writeToParcel(android::Parcel* parcel) const {
    if (parcel == NULL) {
        ALOGE("%s: Null parcel", __FUNCTION__);
        return BAD_VALUE;
    }

    status_t err = OK;

    int32_t settingsCount = static_cast<int32_t>(mPhysicalCameraSettings.size());

    if ((err = parcel->writeInt32(settingsCount)) != OK) {
        ALOGE("%s: Failed to write settings count!", __FUNCTION__);
        return err;
    }

    for (const auto &it : mPhysicalCameraSettings) {
        if ((err = parcel->writeString16(toString16(it.id))) != OK) {
            ALOGE("%s: Failed to camera id!", __FUNCTION__);
            return err;
        }

        if ((err = it.settings.writeToParcel(parcel)) != OK) {
            ALOGE("%s: Failed to write settings!", __FUNCTION__);
            return err;
        }
    }

    parcel->writeInt32(mIsReprocess ? 1 : 0);

    if (mSurfaceConverted) {
        parcel->writeInt32(0); // 0-sized array
    } else {
        int32_t size = static_cast<int32_t>(mSurfaceList.size());

        // Send 0-sized arrays when it's empty. Do not send null arrays.
        parcel->writeInt32(size);

        for (int32_t i = 0; i < size; ++i) {
            // not sure if readParcelableArray does this, hard to tell from source
            parcel->writeString16(String16("android.view.Surface"));

            // Surface.writeToParcel
#if WB_LIBCAMERASERVICE_WITH_DEPENDENCIES
            view::Surface surfaceShim = view::Surface::fromSurface(mSurfaceList[i]);
#else
            view::Surface surfaceShim;
            surfaceShim.name = String16("unknown_name");
            surfaceShim.graphicBufferProducer = mSurfaceList[i]->getIGraphicBufferProducer();
#endif
            if ((err = surfaceShim.writeToParcel(parcel)) != OK) {
                ALOGE("%s: Failed to write output target Surface %d to parcel: %s (%d)",
                        __FUNCTION__, i, strerror(-err), err);
                return err;
            }
        }
    }

    parcel->writeInt32(mStreamIdxList.size());
    for (size_t i = 0; i < mStreamIdxList.size(); ++i) {
        if ((err = parcel->writeInt32(mStreamIdxList[i])) != OK) {
            ALOGE("%s: Failed to write stream index to parcel", __FUNCTION__);
            return err;
        }
        if ((err = parcel->writeInt32(mSurfaceIdxList[i])) != OK) {
            ALOGE("%s: Failed to write surface index to parcel", __FUNCTION__);
            return err;
        }
    }

    if (mUserTag.empty()) {
        parcel->writeInt32(0);
    } else {
        parcel->writeInt32(1);
        parcel->writeString16(toString16(mUserTag));
    }

    return OK;
}

} // namespace camera2
} // namespace hardware
} // namespace android
