/*
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright 2015 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 "EGLImageWrapper.h"
#include <cutils/native_handle.h>
#include <gralloc_priv.h>
#include <ui/GraphicBuffer.h>
#include <fcntl.h>
#include <string>
#include <map>
#include <utility>

using std::string;
using std::map;
using std::pair;

static string pidString = std::to_string(getpid());

#ifndef TARGET_ION_ABI_VERSION
//-----------------------------------------------------------------------------
static void free_ion_cookie(int ion_fd, int cookie)
//-----------------------------------------------------------------------------
{
  if (ion_fd && !ioctl(ion_fd, ION_IOC_FREE, &cookie)) {
  } else {
      ALOGE("ION_IOC_FREE failed: ion_fd = %d, cookie = %d", ion_fd, cookie);
  }
}

//-----------------------------------------------------------------------------
static int get_ion_cookie(int ion_fd, int fd)
//-----------------------------------------------------------------------------
{
  int cookie = fd;

  struct ion_fd_data fdData;
  memset(&fdData, 0, sizeof(fdData));
  fdData.fd = fd;

  if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) {
       cookie = fdData.handle;
  } else {
       ALOGE("ION_IOC_IMPORT failed: ion_fd = %d, fd = %d", ion_fd, fd);
  }

  return cookie;
}
#else
//-----------------------------------------------------------------------------
static string get_ion_buff_str(int buff_fd)
//-----------------------------------------------------------------------------
{
  string retStr = {};
  if (buff_fd >= 0) {
    string fdString = std::to_string(buff_fd);
    string symlinkPath = "/proc/"+pidString+"/fd/"+fdString;
    char buffer[1024] = {};
    ssize_t ret = ::readlink(symlinkPath.c_str(), buffer, sizeof(buffer) - 1);
    if (ret != -1) {
      buffer[ret] = '\0';
      retStr = buffer;
    }
  }

  return retStr;
}
#endif

//-----------------------------------------------------------------------------
void EGLImageWrapper::DeleteEGLImageCallback::operator()(int& buffInt, EGLImageBuffer*& eglImage)
//-----------------------------------------------------------------------------
{
  if (eglImage != 0) {
    delete eglImage;
  }

#ifndef TARGET_ION_ABI_VERSION
  free_ion_cookie(ion_fd, buffInt /* cookie */);
#else
  if (!mapClearPending) {
    for (auto it = buffStrbuffIntMapPtr->begin(); it != buffStrbuffIntMapPtr->end(); it++) {
      if (it->second == buffInt /* counter */) {
        buffStrbuffIntMapPtr->erase(it);
        return;
      }
    }
  }
#endif
}

//-----------------------------------------------------------------------------
EGLImageWrapper::EGLImageWrapper()
//-----------------------------------------------------------------------------
{
  eglImageBufferCache = new android::LruCache<int, EGLImageBuffer*>(32);
  callback = new DeleteEGLImageCallback(&buffStrbuffIntMap);
  eglImageBufferCache->setOnEntryRemovedListener(callback);

#ifndef TARGET_ION_ABI_VERSION
  ion_fd = open("/dev/ion", O_RDONLY);
  callback->ion_fd = ion_fd;
#endif
}

//-----------------------------------------------------------------------------
EGLImageWrapper::~EGLImageWrapper()
//-----------------------------------------------------------------------------
{
  if (eglImageBufferCache != 0) {
    if (callback != 0) {
      callback->mapClearPending = true;
    }
    eglImageBufferCache->clear();
    delete eglImageBufferCache;
    eglImageBufferCache = 0;
    buffStrbuffIntMap.clear();
  }

  if (callback != 0) {
    delete callback;
    callback = 0;
  }

#ifndef TARGET_ION_ABI_VERSION
  if (ion_fd > 0) {
    close(ion_fd);
    ion_fd = -1;
  }
#endif
}

//-----------------------------------------------------------------------------
static EGLImageBuffer* L_wrap(const private_handle_t *src)
//-----------------------------------------------------------------------------
{
  EGLImageBuffer* result = 0;

  native_handle_t *native_handle = const_cast<private_handle_t *>(src);

  int flags = android::GraphicBuffer::USAGE_HW_TEXTURE |
              android::GraphicBuffer::USAGE_SW_READ_NEVER |
              android::GraphicBuffer::USAGE_SW_WRITE_NEVER;

  if (src->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
    flags |= android::GraphicBuffer::USAGE_PROTECTED;
  }

  android::sp<android::GraphicBuffer> graphicBuffer =
    new android::GraphicBuffer(src->unaligned_width, src->unaligned_height, src->format,
#ifndef __NOUGAT__
                               1,  // Layer count
#endif
                               flags, src->width /*src->stride*/,
                               native_handle, false);

  result = new EGLImageBuffer(graphicBuffer);

  return result;
}

//-----------------------------------------------------------------------------
EGLImageBuffer *EGLImageWrapper::wrap(const void *pvt_handle)
//-----------------------------------------------------------------------------
{
  const private_handle_t *src = static_cast<const private_handle_t *>(pvt_handle);

#ifndef TARGET_ION_ABI_VERSION
  int ion_cookie = get_ion_cookie(ion_fd, src->fd);
  EGLImageBuffer* eglImage = nullptr;
  eglImage = eglImageBufferCache->get(ion_cookie);
  if (eglImage == 0) {
    eglImage = L_wrap(src);
    eglImageBufferCache->put(ion_cookie, eglImage);
  } else {
    free_ion_cookie(ion_fd, ion_cookie);
  }
#else
  string buffStr = get_ion_buff_str(src->fd);
  EGLImageBuffer* eglImage = nullptr;
  if (!buffStr.empty()) {
    auto it = buffStrbuffIntMap.find(buffStr);
    if (it != buffStrbuffIntMap.end()) {
      eglImage = eglImageBufferCache->get(it->second);
    } else {
        eglImage = L_wrap(src);
        buffStrbuffIntMap.insert(pair<string, int>(buffStr, buffInt));
        eglImageBufferCache->put(buffInt, eglImage);
        buffInt++;
    }
  } else {
    ALOGE("Could not provide an eglImage for fd = %d, EGLImageWrapper = %p", src->fd, this);
  }
#endif

  return eglImage;
}
