/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#include <log/log.h>
#include <cinttypes>
#include <gralloc_priv.h>
#include "qdMetaData.h"

unsigned long getMetaDataSize() {
    return static_cast<unsigned long>(ROUND_UP_PAGESIZE(sizeof(MetaData_t)));
}

static int validateAndMap(private_handle_t* handle) {
    if (private_handle_t::validate(handle)) {
        ALOGE("%s: Private handle is invalid - handle:%p", __func__, handle);
        return -1;
    }
    if (handle->fd_metadata < 0) {
        // Silently return, metadata cannot be used
        return -1;
    }

    if (!handle->base_metadata) {
        auto size = getMetaDataSize();
        void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
                handle->fd_metadata, 0);
        if (base == reinterpret_cast<void*>(MAP_FAILED)) {
            ALOGE("%s: metadata mmap failed - handle:%p fd: %d err: %s",
                __func__, handle, handle->fd_metadata, strerror(errno));

            return -1;
        }
        handle->base_metadata = (uintptr_t) base;
    }
    return 0;
}

static void unmapAndReset(private_handle_t *handle) {
    if (private_handle_t::validate(handle) == 0 && handle->base_metadata) {
        munmap(reinterpret_cast<void *>(handle->base_metadata), getMetaDataSize());
        handle->base_metadata = 0;
    }
}

int setMetaData(private_handle_t *handle, DispParamType paramType,
                void *param) {
    auto err = validateAndMap(handle);
    if (err != 0)
        return err;
    return setMetaDataVa(reinterpret_cast<MetaData_t*>(handle->base_metadata),
                         paramType, param);
}

int setMetaDataVa(MetaData_t *data, DispParamType paramType,
                  void *param) {
    if (data == nullptr)
        return -EINVAL;
    // If parameter is NULL reset the specific MetaData Key
    if (!param) {
       data->operation &= ~paramType;
       // param unset
       return 0;
    }

    data->operation |= paramType;
    switch (paramType) {
        case PP_PARAM_INTERLACED:
            data->interlaced = *((int32_t *)param);
            break;
        case UPDATE_BUFFER_GEOMETRY:
            data->bufferDim = *((BufferDim_t *)param);
            break;
        case UPDATE_REFRESH_RATE:
            data->refreshrate = *((float *)param);
            break;
        case UPDATE_COLOR_SPACE:
            data->colorSpace = *((ColorSpace_t *)param);
            break;
        case MAP_SECURE_BUFFER:
            data->mapSecureBuffer = *((int32_t *)param);
            break;
        case S3D_FORMAT:
            data->s3dFormat = *((uint32_t *)param);
            break;
        case LINEAR_FORMAT:
            data->linearFormat = *((uint32_t *)param);
            break;
        case SET_IGC:
            data->igc = *((IGC_t *)param);
            break;
        case SET_SINGLE_BUFFER_MODE:
            data->isSingleBufferMode = *((uint32_t *)param);
            break;
        case SET_S3D_COMP:
            data->s3dComp = *((S3DGpuComp_t *)param);
            break;
        case SET_VT_TIMESTAMP:
            data->vtTimeStamp = *((uint64_t *)param);
            break;
        case COLOR_METADATA:
            data->color = *((ColorMetaData *)param);
            break;
        case SET_UBWC_CR_STATS_INFO: {
             struct UBWCStats* stats = (struct UBWCStats*)param;
             int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
             for (int i = 0; i < numelems; i++) {
                  data->ubwcCRStats[i] = stats[i];
             }
              break;
          }
        case SET_VIDEO_PERF_MODE:
            data->isVideoPerfMode = *((uint32_t *)param);
            break;
        case SET_GRAPHICS_METADATA: {
             GraphicsMetadata payload = *((GraphicsMetadata*)(param));
             data->graphics_metadata.size = payload.size;
             memcpy(data->graphics_metadata.data, payload.data,
                    sizeof(data->graphics_metadata.data));
             break;
        }
        default:
            ALOGE("Unknown paramType %d", paramType);
            break;
    }
    return 0;
}

int clearMetaData(private_handle_t *handle, DispParamType paramType) {
    auto err = validateAndMap(handle);
    if (err != 0)
        return err;
    return clearMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
            paramType);
}

int clearMetaDataVa(MetaData_t *data, DispParamType paramType) {
    if (data == nullptr)
        return -EINVAL;
    data->operation &= ~paramType;
    switch (paramType) {
        case SET_S3D_COMP:
            data->s3dComp.displayId = -1;
            data->s3dComp.s3dMode = 0;
            break;
        default:
            ALOGE("Unknown paramType %d", paramType);
            break;
    }
    return 0;
}

int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
                                                    void *param) {
    int ret = validateAndMap(handle);
    if (ret != 0)
        return ret;
    return getMetaDataVa(reinterpret_cast<MetaData_t *>(handle->base_metadata),
                         paramType, param);
}

int getMetaDataVa(MetaData_t *data, DispFetchParamType paramType,
                  void *param) {
    // Make sure we send 0 only if the operation queried is present
    int ret = -EINVAL;
    if (data == nullptr)
        return ret;
    if (param == nullptr)
        return ret;

    switch (paramType) {
        case GET_PP_PARAM_INTERLACED:
            if (data->operation & PP_PARAM_INTERLACED) {
                *((int32_t *)param) = data->interlaced;
                ret = 0;
            }
            break;
        case GET_BUFFER_GEOMETRY:
            if (data->operation & UPDATE_BUFFER_GEOMETRY) {
                *((BufferDim_t *)param) = data->bufferDim;
                ret = 0;
            }
            break;
        case GET_REFRESH_RATE:
            if (data->operation & UPDATE_REFRESH_RATE) {
                *((float *)param) = data->refreshrate;
                ret = 0;
            }
            break;
        case GET_COLOR_SPACE:
            if (data->operation & UPDATE_COLOR_SPACE) {
                *((ColorSpace_t *)param) = data->colorSpace;
                ret = 0;
            }
            break;
        case GET_MAP_SECURE_BUFFER:
            if (data->operation & MAP_SECURE_BUFFER) {
                *((int32_t *)param) = data->mapSecureBuffer;
                ret = 0;
            }
            break;
        case GET_S3D_FORMAT:
            if (data->operation & S3D_FORMAT) {
                *((uint32_t *)param) = data->s3dFormat;
                ret = 0;
            }
            break;
        case GET_LINEAR_FORMAT:
            if (data->operation & LINEAR_FORMAT) {
                *((uint32_t *)param) = data->linearFormat;
                ret = 0;
            }
            break;
        case GET_IGC:
            if (data->operation & SET_IGC) {
                *((IGC_t *)param) = data->igc;
                ret = 0;
            }
            break;
        case GET_SINGLE_BUFFER_MODE:
            if (data->operation & SET_SINGLE_BUFFER_MODE) {
                *((uint32_t *)param) = data->isSingleBufferMode;
                ret = 0;
            }
            break;
        case GET_S3D_COMP:
            if (data->operation & SET_S3D_COMP) {
                *((S3DGpuComp_t *)param) = data->s3dComp;
                ret = 0;
            }
            break;
        case GET_VT_TIMESTAMP:
            if (data->operation & SET_VT_TIMESTAMP) {
                *((uint64_t *)param) = data->vtTimeStamp;
                ret = 0;
            }
            break;
        case GET_COLOR_METADATA:
            if (data->operation & COLOR_METADATA) {
                *((ColorMetaData *)param) = data->color;
                ret = 0;
            }
            break;
        case GET_UBWC_CR_STATS_INFO:
            if (data->operation & SET_UBWC_CR_STATS_INFO) {
                struct UBWCStats* stats = (struct UBWCStats*)param;
                int numelems = sizeof(data->ubwcCRStats) / sizeof(struct UBWCStats);
                for (int i = 0; i < numelems; i++) {
                    stats[i] = data->ubwcCRStats[i];
                }
                ret = 0;
            }
            break;
        case GET_VIDEO_PERF_MODE:
            if (data->operation & SET_VIDEO_PERF_MODE) {
                *((uint32_t *)param) = data->isVideoPerfMode;
                ret = 0;
            }
            break;
        case GET_GRAPHICS_METADATA:
            if (data->operation & SET_GRAPHICS_METADATA) {
                memcpy(param, data->graphics_metadata.data, sizeof(data->graphics_metadata.data));
                ret = 0;
            }
            break;
        default:
            ALOGE("Unknown paramType %d", paramType);
            break;
    }
    return ret;
}

int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst) {
    auto err = validateAndMap(src);
    if (err != 0)
        return err;

    err = validateAndMap(dst);
    if (err != 0)
        return err;

    MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
    MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
    *dst_data = *src_data;
    return 0;
}

int copyMetaDataVaToHandle(MetaData_t *src_data, struct private_handle_t *dst) {
    int err = -EINVAL;
    if (src_data == nullptr)
        return err;

    err = validateAndMap(dst);
    if (err != 0)
        return err;

    MetaData_t *dst_data = reinterpret_cast <MetaData_t *>(dst->base_metadata);
    *dst_data = *src_data;
    return 0;
}

int copyMetaDataHandleToVa(struct private_handle_t *src, MetaData_t *dst_data) {
    int err = -EINVAL;
    if (dst_data == nullptr)
        return err;

    err = validateAndMap(src);
    if (err != 0)
        return err;

    MetaData_t *src_data = reinterpret_cast <MetaData_t *>(src->base_metadata);
    *dst_data = *src_data;
    return 0;
}

int copyMetaDataVaToVa(MetaData_t *src_data, MetaData_t *dst_data) {
    int err = -EINVAL;
    if (src_data == nullptr)
        return err;

    if (dst_data == nullptr)
        return err;

    *dst_data = *src_data;
    return 0;
}

int setMetaDataAndUnmap(struct private_handle_t *handle, enum DispParamType paramType,
                        void *param) {
    auto ret = setMetaData(handle, paramType, param);
    unmapAndReset(handle);
    return ret;
}

int getMetaDataAndUnmap(struct private_handle_t *handle,
                        enum DispFetchParamType paramType,
                        void *param) {
    auto ret = getMetaData(handle, paramType, param);
    unmapAndReset(handle);
    return ret;
}

