/*
 * Copyright 2016 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.
 */

#undef LOG_TAG
#define LOG_TAG "Gralloc1On0Adapter"
//#define LOG_NDEBUG 0

#include <hardware/gralloc.h>

#include <ui/Gralloc1On0Adapter.h>

#include <utils/Log.h>

#include <inttypes.h>

template <typename PFN, typename T>
static gralloc1_function_pointer_t asFP(T function)
{
    static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
    return reinterpret_cast<gralloc1_function_pointer_t>(function);
}

namespace android {

Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module)
  : mModule(reinterpret_cast<const gralloc_module_t*>(module)),
    mMinorVersion(mModule->common.module_api_version & 0xFF),
    mDevice(nullptr)
{
    ALOGV("Constructing");
    getCapabilities = getCapabilitiesHook;
    getFunction = getFunctionHook;
    int error = ::gralloc_open(&(mModule->common), &mDevice);
    if (error) {
        ALOGE("Failed to open gralloc0 module: %d", error);
    }
    ALOGV("Opened gralloc0 device %p", mDevice);
}

Gralloc1On0Adapter::~Gralloc1On0Adapter()
{
    ALOGV("Destructing");
    if (mDevice) {
        ALOGV("Closing gralloc0 device %p", mDevice);
        ::gralloc_close(mDevice);
    }
}

void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
        int32_t* outCapabilities)
{
    if (outCapabilities == nullptr) {
        *outCount = 1;
        return;
    }
    if (*outCount >= 1) {
        *outCapabilities = GRALLOC1_CAPABILITY_ON_ADAPTER;
        *outCount = 1;
    }
}

gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction(
        int32_t intDescriptor)
{
    constexpr auto lastDescriptor =
            static_cast<int32_t>(GRALLOC1_LAST_ADAPTER_FUNCTION);
    if (intDescriptor < 0 || intDescriptor > lastDescriptor) {
        ALOGE("Invalid function descriptor");
        return nullptr;
    }

    auto descriptor =
            static_cast<gralloc1_function_descriptor_t>(intDescriptor);
    switch (descriptor) {
        case GRALLOC1_FUNCTION_DUMP:
            return asFP<GRALLOC1_PFN_DUMP>(dumpHook);
        case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
            return asFP<GRALLOC1_PFN_CREATE_DESCRIPTOR>(createDescriptorHook);
        case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
            return asFP<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(destroyDescriptorHook);
        case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
            return asFP<GRALLOC1_PFN_SET_CONSUMER_USAGE>(setConsumerUsageHook);
        case GRALLOC1_FUNCTION_SET_DIMENSIONS:
            return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook);
        case GRALLOC1_FUNCTION_SET_FORMAT:
            return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook);
        case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
            return asFP<GRALLOC1_PFN_SET_LAYER_COUNT>(setLayerCountHook);
        case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
            return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook);
        case GRALLOC1_FUNCTION_GET_BACKING_STORE:
            return asFP<GRALLOC1_PFN_GET_BACKING_STORE>(
                    bufferHook<decltype(&Buffer::getBackingStore),
                    &Buffer::getBackingStore, gralloc1_backing_store_t*>);
        case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
            return asFP<GRALLOC1_PFN_GET_CONSUMER_USAGE>(getConsumerUsageHook);
        case GRALLOC1_FUNCTION_GET_DIMENSIONS:
            return asFP<GRALLOC1_PFN_GET_DIMENSIONS>(
                    bufferHook<decltype(&Buffer::getDimensions),
                    &Buffer::getDimensions, uint32_t*, uint32_t*>);
        case GRALLOC1_FUNCTION_GET_FORMAT:
            return asFP<GRALLOC1_PFN_GET_FORMAT>(
                    bufferHook<decltype(&Buffer::getFormat),
                    &Buffer::getFormat, int32_t*>);
        case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
            return asFP<GRALLOC1_PFN_GET_LAYER_COUNT>(
                    bufferHook<decltype(&Buffer::getLayerCount),
                    &Buffer::getLayerCount, uint32_t*>);
        case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
            return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
        case GRALLOC1_FUNCTION_GET_STRIDE:
            return asFP<GRALLOC1_PFN_GET_STRIDE>(
                    bufferHook<decltype(&Buffer::getStride),
                    &Buffer::getStride, uint32_t*>);
        case GRALLOC1_FUNCTION_ALLOCATE:
            // Not provided, since we'll use ALLOCATE_WITH_ID
            return nullptr;
        case GRALLOC1_FUNCTION_ALLOCATE_WITH_ID:
            if (mDevice != nullptr) {
                return asFP<GRALLOC1_PFN_ALLOCATE_WITH_ID>(allocateWithIdHook);
            } else {
                return nullptr;
            }
        case GRALLOC1_FUNCTION_RETAIN:
            return asFP<GRALLOC1_PFN_RETAIN>(
                    managementHook<&Gralloc1On0Adapter::retain>);
        case GRALLOC1_FUNCTION_RELEASE:
            return asFP<GRALLOC1_PFN_RELEASE>(
                    managementHook<&Gralloc1On0Adapter::release>);
        case GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER:
            return asFP<GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER>(
                    retainGraphicBufferHook);
        case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
            return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>(
                    bufferHook<decltype(&Buffer::getNumFlexPlanes),
                    &Buffer::getNumFlexPlanes, uint32_t*>);
        case GRALLOC1_FUNCTION_LOCK:
            return asFP<GRALLOC1_PFN_LOCK>(
                    lockHook<void*, &Gralloc1On0Adapter::lock>);
        case GRALLOC1_FUNCTION_LOCK_FLEX:
            return asFP<GRALLOC1_PFN_LOCK_FLEX>(
                    lockHook<struct android_flex_layout,
                    &Gralloc1On0Adapter::lockFlex>);
        case GRALLOC1_FUNCTION_LOCK_YCBCR:
            return asFP<GRALLOC1_PFN_LOCK_YCBCR>(
                    lockHook<struct android_ycbcr,
                    &Gralloc1On0Adapter::lockYCbCr>);
        case GRALLOC1_FUNCTION_UNLOCK:
            return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
        case GRALLOC1_FUNCTION_INVALID:
            ALOGE("Invalid function descriptor");
            return nullptr;
    }

    ALOGE("Unknown function descriptor: %d", intDescriptor);
    return nullptr;
}

void Gralloc1On0Adapter::dump(uint32_t* outSize, char* outBuffer)
{
    ALOGV("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer);

    if (!mDevice->dump) {
        // dump is optional on gralloc0 implementations
        *outSize = 0;
        return;
    }

    if (!outBuffer) {
        constexpr int32_t BUFFER_LENGTH = 4096;
        char buffer[BUFFER_LENGTH] = {};
        mDevice->dump(mDevice, buffer, BUFFER_LENGTH);
        buffer[BUFFER_LENGTH - 1] = 0; // Ensure the buffer is null-terminated
        size_t actualLength = std::strlen(buffer);
        mCachedDump.resize(actualLength);
        std::copy_n(buffer, actualLength, mCachedDump.begin());
        *outSize = static_cast<uint32_t>(actualLength);
    } else {
        *outSize = std::min(*outSize,
                static_cast<uint32_t>(mCachedDump.size()));
        outBuffer = std::copy_n(mCachedDump.cbegin(), *outSize, outBuffer);
    }
}

gralloc1_error_t Gralloc1On0Adapter::createDescriptor(
        gralloc1_buffer_descriptor_t* outDescriptor)
{
    auto descriptorId = sNextBufferDescriptorId++;
    std::lock_guard<std::mutex> lock(mDescriptorMutex);
    mDescriptors.emplace(descriptorId,
            std::make_shared<Descriptor>(this, descriptorId));

    ALOGV("Created descriptor %" PRIu64, descriptorId);

    *outDescriptor = descriptorId;
    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::destroyDescriptor(
        gralloc1_buffer_descriptor_t descriptor)
{
    ALOGV("Destroying descriptor %" PRIu64, descriptor);

    std::lock_guard<std::mutex> lock(mDescriptorMutex);
    if (mDescriptors.count(descriptor) == 0) {
        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
    }

    mDescriptors.erase(descriptor);
    return GRALLOC1_ERROR_NONE;
}

Gralloc1On0Adapter::Buffer::Buffer(buffer_handle_t handle,
        gralloc1_backing_store_t store, const Descriptor& descriptor,
        uint32_t stride, bool wasAllocated)
  : mHandle(handle),
    mReferenceCount(1),
    mStore(store),
    mDescriptor(descriptor),
    mStride(stride),
    mWasAllocated(wasAllocated) {}

gralloc1_error_t Gralloc1On0Adapter::allocate(
        const std::shared_ptr<Descriptor>& descriptor,
        gralloc1_backing_store_t store,
        buffer_handle_t* outBufferHandle)
{
    ALOGV("allocate(%" PRIu64 ", %#" PRIx64 ")", descriptor->id, store);

    // If this function is being called, it's because we handed out its function
    // pointer, which only occurs when mDevice has been loaded successfully and
    // we are permitted to allocate

    int usage = static_cast<int>(descriptor->producerUsage) |
            static_cast<int>(descriptor->consumerUsage);
    buffer_handle_t handle = nullptr;
    int stride = 0;
    ALOGV("Calling alloc(%p, %u, %u, %i, %u)", mDevice, descriptor->width,
            descriptor->height, descriptor->format, usage);
    auto error = mDevice->alloc(mDevice,
            static_cast<int>(descriptor->width),
            static_cast<int>(descriptor->height), descriptor->format,
            usage, &handle, &stride);
    if (error != 0) {
        ALOGE("gralloc0 allocation failed: %d (%s)", error,
                strerror(-error));
        return GRALLOC1_ERROR_NO_RESOURCES;
    }

    *outBufferHandle = handle;
    auto buffer = std::make_shared<Buffer>(handle, store, *descriptor, stride,
            true);

    std::lock_guard<std::mutex> lock(mBufferMutex);
    mBuffers.emplace(handle, std::move(buffer));

    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::allocateWithIdHook(
        gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptorId,
        gralloc1_backing_store_t store, buffer_handle_t* outBuffer)
{
    auto adapter = getAdapter(device);

    auto descriptor = adapter->getDescriptor(descriptorId);
    if (!descriptor) {
        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
    }

    buffer_handle_t bufferHandle = nullptr;
    auto error = adapter->allocate(descriptor, store, &bufferHandle);
    if (error != GRALLOC1_ERROR_NONE) {
        return error;
    }

    *outBuffer = bufferHandle;
    return error;
}

gralloc1_error_t Gralloc1On0Adapter::retain(
        const std::shared_ptr<Buffer>& buffer)
{
    std::lock_guard<std::mutex> lock(mBufferMutex);
    buffer->retain();
    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::release(
        const std::shared_ptr<Buffer>& buffer)
{
    std::lock_guard<std::mutex> lock(mBufferMutex);
    if (!buffer->release()) {
        return GRALLOC1_ERROR_NONE;
    }

    buffer_handle_t handle = buffer->getHandle();
    if (buffer->wasAllocated()) {
        ALOGV("Calling free(%p)", handle);
        int result = mDevice->free(mDevice, handle);
        if (result != 0) {
            ALOGE("gralloc0 free failed: %d", result);
        }
    } else {
        ALOGV("Calling unregisterBuffer(%p)", handle);
        int result = mModule->unregisterBuffer(mModule, handle);
        if (result != 0) {
            ALOGE("gralloc0 unregister failed: %d", result);
        }
    }

    mBuffers.erase(handle);
    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::retain(
        const android::GraphicBuffer* graphicBuffer)
{
    ALOGV("retainGraphicBuffer(%p, %#" PRIx64 ")",
            graphicBuffer->getNativeBuffer()->handle, graphicBuffer->getId());

    buffer_handle_t handle = graphicBuffer->getNativeBuffer()->handle;
    std::lock_guard<std::mutex> lock(mBufferMutex);
    if (mBuffers.count(handle) != 0) {
        mBuffers[handle]->retain();
        return GRALLOC1_ERROR_NONE;
    }

    ALOGV("Calling registerBuffer(%p)", handle);
    int result = mModule->registerBuffer(mModule, handle);
    if (result != 0) {
        ALOGE("gralloc0 register failed: %d", result);
        return GRALLOC1_ERROR_NO_RESOURCES;
    }

    Descriptor descriptor{this, sNextBufferDescriptorId++};
    descriptor.setDimensions(graphicBuffer->getWidth(),
            graphicBuffer->getHeight());
    descriptor.setFormat(graphicBuffer->getPixelFormat());
    descriptor.setProducerUsage(
            static_cast<gralloc1_producer_usage_t>(graphicBuffer->getUsage()));
    descriptor.setConsumerUsage(
            static_cast<gralloc1_consumer_usage_t>(graphicBuffer->getUsage()));
    auto buffer = std::make_shared<Buffer>(handle,
            static_cast<gralloc1_backing_store_t>(graphicBuffer->getId()),
            descriptor, graphicBuffer->getStride(), false);
    mBuffers.emplace(handle, std::move(buffer));
    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::lock(
        const std::shared_ptr<Buffer>& buffer,
        gralloc1_producer_usage_t producerUsage,
        gralloc1_consumer_usage_t consumerUsage,
        const gralloc1_rect_t& accessRegion, void** outData,
        const sp<Fence>& acquireFence)
{
    if (mMinorVersion >= 3) {
        int result = mModule->lockAsync(mModule, buffer->getHandle(),
                static_cast<int32_t>(producerUsage | consumerUsage),
                accessRegion.left, accessRegion.top, accessRegion.width,
                accessRegion.height, outData, acquireFence->dup());
        if (result != 0) {
            return GRALLOC1_ERROR_UNSUPPORTED;
        }
    } else {
        acquireFence->waitForever("Gralloc1On0Adapter::lock");
        int result = mModule->lock(mModule, buffer->getHandle(),
                static_cast<int32_t>(producerUsage | consumerUsage),
                accessRegion.left, accessRegion.top, accessRegion.width,
                accessRegion.height, outData);
        ALOGV("gralloc0 lock returned %d", result);
        if (result != 0) {
            return GRALLOC1_ERROR_UNSUPPORTED;
        }
    }
    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::lockFlex(
        const std::shared_ptr<Buffer>& /*buffer*/,
        gralloc1_producer_usage_t /*producerUsage*/,
        gralloc1_consumer_usage_t /*consumerUsage*/,
        const gralloc1_rect_t& /*accessRegion*/,
        struct android_flex_layout* /*outData*/,
        const sp<Fence>& /*acquireFence*/)
{
    // TODO
    return GRALLOC1_ERROR_UNSUPPORTED;
}

gralloc1_error_t Gralloc1On0Adapter::lockYCbCr(
        const std::shared_ptr<Buffer>& buffer,
        gralloc1_producer_usage_t producerUsage,
        gralloc1_consumer_usage_t consumerUsage,
        const gralloc1_rect_t& accessRegion, struct android_ycbcr* outData,
        const sp<Fence>& acquireFence)
{
    if (mMinorVersion >= 3 && mModule->lockAsync_ycbcr) {
        int result = mModule->lockAsync_ycbcr(mModule, buffer->getHandle(),
                static_cast<int>(producerUsage | consumerUsage),
                accessRegion.left, accessRegion.top, accessRegion.width,
                accessRegion.height, outData, acquireFence->dup());
        if (result != 0) {
            return GRALLOC1_ERROR_UNSUPPORTED;
        }
    } else if (mModule->lock_ycbcr) {
        acquireFence->waitForever("Gralloc1On0Adapter::lockYCbCr");
        int result = mModule->lock_ycbcr(mModule, buffer->getHandle(),
                static_cast<int>(producerUsage | consumerUsage),
                accessRegion.left, accessRegion.top, accessRegion.width,
                accessRegion.height, outData);
        ALOGV("gralloc0 lockYCbCr returned %d", result);
        if (result != 0) {
            return GRALLOC1_ERROR_UNSUPPORTED;
        }
    } else {
        return GRALLOC1_ERROR_UNSUPPORTED;
    }

    return GRALLOC1_ERROR_NONE;
}

gralloc1_error_t Gralloc1On0Adapter::unlock(
        const std::shared_ptr<Buffer>& buffer,
        sp<Fence>* outReleaseFence)
{
    if (mMinorVersion >= 3) {
        int fenceFd = -1;
        int result = mModule->unlockAsync(mModule, buffer->getHandle(),
                &fenceFd);
        if (result != 0) {
            close(fenceFd);
            ALOGE("gralloc0 unlockAsync failed: %d", result);
        } else {
            *outReleaseFence = new Fence(fenceFd);
        }
    } else {
        int result = mModule->unlock(mModule, buffer->getHandle());
        if (result != 0) {
            ALOGE("gralloc0 unlock failed: %d", result);
        }
    }
    return GRALLOC1_ERROR_NONE;
}

std::shared_ptr<Gralloc1On0Adapter::Descriptor>
Gralloc1On0Adapter::getDescriptor(gralloc1_buffer_descriptor_t descriptorId)
{
    std::lock_guard<std::mutex> lock(mDescriptorMutex);
    if (mDescriptors.count(descriptorId) == 0) {
        return nullptr;
    }

    return mDescriptors[descriptorId];
}

std::shared_ptr<Gralloc1On0Adapter::Buffer> Gralloc1On0Adapter::getBuffer(
        buffer_handle_t bufferHandle)
{
    std::lock_guard<std::mutex> lock(mBufferMutex);
    if (mBuffers.count(bufferHandle) == 0) {
        return nullptr;
    }

    return mBuffers[bufferHandle];
}

std::atomic<gralloc1_buffer_descriptor_t>
        Gralloc1On0Adapter::sNextBufferDescriptorId(1);

} // namespace android
