// Copyright 2024 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.

#include <cstdint>
#include <memory>
#include <optional>
#include <vector>

#include "VirtGpu.h"
#include "gfxstream/guest/Gralloc.h"

namespace gfxstream {

using EGLClientBuffer = void*;

class EmulatedAHardwareBuffer {
   public:
    EmulatedAHardwareBuffer(uint32_t width, uint32_t height, uint32_t drmFormat,
                            VirtGpuResourcePtr resource);

    ~EmulatedAHardwareBuffer();

    uint32_t getResourceId() const;

    uint32_t getWidth() const;

    uint32_t getHeight() const;

    int getAndroidFormat() const;

    uint32_t getDrmFormat() const;

    AHardwareBuffer* asAHardwareBuffer();

    buffer_handle_t asBufferHandle();

    EGLClientBuffer asEglClientBuffer();

    void acquire();
    void release();

    int lock(uint8_t** ptr);
    int lockPlanes(std::vector<Gralloc::LockedPlane>* ahbPlanes);
    int unlock();

   private:
    uint32_t mRefCount;
    uint32_t mWidth;
    uint32_t mHeight;
    uint32_t mDrmFormat;
    VirtGpuResourcePtr mResource;
    std::optional<VirtGpuResourceMappingPtr> mMapped;
};

class EmulatedGralloc : public Gralloc {
   public:
    EmulatedGralloc(VirtGpuDevice* device);
    ~EmulatedGralloc();
    uint32_t createColorBuffer(void*, int width, int height, uint32_t glFormat) override;

    int allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
                 AHardwareBuffer** outputAhb) override;

    AHardwareBuffer* allocate(uint32_t width, uint32_t height, uint32_t format);

    void acquire(AHardwareBuffer* ahb) override;
    void release(AHardwareBuffer* ahb) override;

    int lock(AHardwareBuffer* ahb, uint8_t** ptr) override;
    int lockPlanes(AHardwareBuffer* ahb, std::vector<LockedPlane>* ahbPlanes) override;
    int unlock(AHardwareBuffer* ahb) override;

    uint32_t getHostHandle(const native_handle_t* handle) override;
    uint32_t getHostHandle(const AHardwareBuffer* handle) override;

    const native_handle_t* getNativeHandle(const AHardwareBuffer* ahb) override;

    int getFormat(const native_handle_t* handle) override;
    int getFormat(const AHardwareBuffer* handle) override;

    uint32_t getFormatDrmFourcc(const AHardwareBuffer* handle) override;

    uint32_t getWidth(const AHardwareBuffer* ahb) override;
    uint32_t getHeight(const AHardwareBuffer* ahb) override;

    size_t getAllocatedSize(const native_handle_t*) override;
    size_t getAllocatedSize(const AHardwareBuffer*) override;

    int getId(const AHardwareBuffer* ahb, uint64_t* id) override;

   private:
    VirtGpuDevice* mDevice;
    std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> mOwned;
};

}  // namespace gfxstream
