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

#pragma once

#include <android-base/unique_fd.h>
#include <system/window.h>
#include <apex/window.h>
#include <utils/Errors.h>
#include <utils/Macros.h>
#ifdef __ANDROID__
#include <utils/NdkUtils.h>
#endif
#include <utils/StrongPointer.h>

#include <memory>
#include <mutex>

namespace android::uirenderer::renderthread {

class ReliableSurface {
    PREVENT_COPY_AND_ASSIGN(ReliableSurface);

public:
    ReliableSurface(ANativeWindow* window);
    ~ReliableSurface();

    // Performs initialization that is not safe to do in the constructor.
    // For instance, registering ANativeWindow interceptors with ReliableSurface
    // passed as the data pointer is not safe.
    void init();

    ANativeWindow* getNativeWindow() { return mWindow; }

    int reserveNext();

    int getAndClearError() {
        int ret = mBufferQueueState;
        mBufferQueueState = OK;
        return ret;
    }

    bool didSetExtraBuffers() const {
        std::lock_guard _lock{mMutex};
        return mDidSetExtraBuffers;
    }

private:
    ANativeWindow* mWindow;

    mutable std::mutex mMutex;

    uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
#ifdef __ANDROID__
    AHardwareBuffer_Format mFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
    UniqueAHardwareBuffer mScratchBuffer;
    ANativeWindowBuffer* mReservedBuffer = nullptr;
#endif
    base::unique_fd mReservedFenceFd;
    bool mHasDequeuedBuffer = false;
    int mBufferQueueState = OK;
    size_t mExpectedBufferCount = 0;
    bool mDidSetExtraBuffers = false;

    bool isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const;
    ANativeWindowBuffer* acquireFallbackBuffer(int error);
    void clearReservedBuffer();

    // ANativeWindow hooks. When an ANativeWindow_* method is called on the
    // underlying ANativeWindow, these methods will intercept the original call.
    // For example, an EGL driver would call into these hooks instead of the
    // original methods.
    static int hook_cancelBuffer(ANativeWindow* window, ANativeWindow_cancelBufferFn cancelBuffer,
                                 void* data, ANativeWindowBuffer* buffer, int fenceFd);
    static int hook_dequeueBuffer(ANativeWindow* window,
                                  ANativeWindow_dequeueBufferFn dequeueBuffer, void* data,
                                  ANativeWindowBuffer** buffer, int* fenceFd);
    static int hook_queueBuffer(ANativeWindow* window, ANativeWindow_queueBufferFn queueBuffer,
                                void* data, ANativeWindowBuffer* buffer, int fenceFd);

    static int hook_perform(ANativeWindow* window, ANativeWindow_performFn perform, void* data,
                            int operation, va_list args);
    static int hook_query(const ANativeWindow* window, ANativeWindow_queryFn query, void* data,
            int what, int* value);
};

};  // namespace android::uirenderer::renderthread
