/*
 * Copyright (c) 2019, 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 <dlfcn.h>
#include <log/log.h>
#include <mutex>

#include "gr_camera_info.h"
#include "gralloc_priv.h"

using std::lock_guard;
using std::mutex;

namespace gralloc {

CameraInfo *CameraInfo::s_instance = nullptr;

CameraInfo *CameraInfo::GetInstance() {
  static mutex s_lock;
  lock_guard<mutex> obj(s_lock);
  if (!s_instance) {
    s_instance = new CameraInfo();
  }

  return s_instance;
}

CameraInfo::CameraInfo() {
  libcamera_utils_ = ::dlopen("libcamxexternalformatutils.so", RTLD_NOW);
  if (libcamera_utils_) {
    *reinterpret_cast<void **>(&LINK_camera_get_stride_in_bytes) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetStrideInBytes");
    *reinterpret_cast<void **>(&LINK_camera_get_stride_in_pixels) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetStrideInPixels");
    *reinterpret_cast<void **>(&LINK_camera_get_scanline) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetScanline");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_size) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneSize");
    *reinterpret_cast<void **>(&LINK_camera_get_buffer_size) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetBufferSize");
    *reinterpret_cast<void **>(&LINK_camera_get_ubwc_info) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetUBWCInfo");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_alignment) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneAlignment");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_offset) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneOffset");
    *reinterpret_cast<void **>(&LINK_camera_is_per_plane_fd_needed) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_IsPerPlaneFdNeeded");
    *reinterpret_cast<void **>(&LINK_camera_get_bpp) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetBpp");
    *reinterpret_cast<void **>(&LINK_camera_get_per_plane_bpp) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPerPlaneBpp");
    *reinterpret_cast<void **>(&LINK_camera_get_subsampling_factor) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetSubsamplingFactor");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_count) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneCount");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_types) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneTypes");
    *reinterpret_cast<void **>(&LINK_camera_get_pixel_increment) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPixelIncrement");
    *reinterpret_cast<void **>(&LINK_camera_get_plane_start_address_alignment) =
        ::dlsym(libcamera_utils_, "CamxFormatUtil_GetPlaneStartAddressAlignment");
  } else {
    ALOGE("%s: Failed to load libcamxexternalformatutils.so - %s", __FUNCTION__, strerror(errno));
  }
}

CameraInfo::~CameraInfo() {
  if (libcamera_utils_) {
    ::dlclose(libcamera_utils_);
  }
}

CamxPixelFormat CameraInfo::GetCameraPixelFormat(int hal_format) {
  CamxPixelFormat format = (CamxPixelFormat)0;
  switch (hal_format) {
    case HAL_PIXEL_FORMAT_NV21_ZSL:
      format = CAMERA_PIXEL_FORMAT_NV21_ZSL;
      break;
    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
      format = CAMERA_PIXEL_FORMAT_YUV_FLEX;
      break;
    case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX:
      format = CAMERA_PIXEL_FORMAT_UBWC_FLEX;
      break;
    case HAL_PIXEL_FORMAT_MULTIPLANAR_FLEX:
      format = CAMERA_PIXEL_FORMAT_MULTIPLANAR_FLEX;
      break;
    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
      format = CAMERA_PIXEL_FORMAT_RAW_OPAQUE;
      break;
    default:
      ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
      break;
  }

  return format;
}

int CameraInfo::GetBufferSize(int format, int width, int height, unsigned int *size) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_buffer_size) {
    result = LINK_camera_get_buffer_size(GetCameraPixelFormat(format), width, height, size);
    if (result != 0) {
      ALOGE("%s: Failed to get the buffer size. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetBufferSize. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetStrideInBytes(int format, int plane_type, int width, int *stride_bytes) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_stride_in_bytes) {
    result = LINK_camera_get_stride_in_bytes(GetCameraPixelFormat(format),
                                             GetCamxPlaneType(plane_type), width, stride_bytes);
    if (result != 0) {
      ALOGE("%s: Failed to get the stride in bytes. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetStrideInBytes. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetStrideInPixels(int format, int plane_type, int width, float *stride_pixel) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_stride_in_pixels) {
    result = LINK_camera_get_stride_in_pixels(GetCameraPixelFormat(format),
                                              GetCamxPlaneType(plane_type), width, stride_pixel);
    if (result != 0) {
      ALOGE("%s: Failed to get the stride in pixels. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetStrideInPixels. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPixelIncrement(int format, int plane_type, int *pixel_increment) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_pixel_increment) {
    result = LINK_camera_get_pixel_increment(GetCameraPixelFormat(format),
                                             GetCamxPlaneType(plane_type), pixel_increment);
    if (result != 0) {
      ALOGE("%s: Failed to get pixel increment. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPixelIncrement. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPlaneOffset(int format, int plane_type, int width, int height, int *offset) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_offset) {
    result = LINK_camera_get_plane_offset(GetCameraPixelFormat(format),
                                          GetCamxPlaneType(plane_type), offset, width, height);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane offset. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneOffset. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetSubsamplingFactor(int format, int plane_type, bool isHorizontal,
                                     int *subsampling_factor) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_subsampling_factor) {
    result = LINK_camera_get_subsampling_factor(GetCameraPixelFormat(format),
                                                GetCamxPlaneType(plane_type), isHorizontal,
                                                subsampling_factor);
    if (result != 0) {
      ALOGE("%s: Failed to get the sub-sampling factor. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetSubsamplingFactor. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPlaneTypes(int format, PlaneComponent *plane_component_array, int *plane_count) {
  CamxPlaneType plane_types_array[8] = {};
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_types) {
    result =
        LINK_camera_get_plane_types(GetCameraPixelFormat(format), plane_types_array, plane_count);
    if (result == 0) {
      for (int plane = 0; plane < *plane_count; plane++) {
        plane_component_array[plane] = GetPlaneComponent(plane_types_array[plane]);
      }
    } else {
      ALOGE("%s: Failed to get the plane types. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneTypes. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetScanline(int format, int plane_type, int height, int *scanlines) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_scanline) {
    result = LINK_camera_get_scanline(GetCameraPixelFormat(format), GetCamxPlaneType(plane_type),
                                      height, scanlines);
    if (result != 0) {
      ALOGE("%s: Failed to get the scanlines. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetScanline. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetPlaneSize(int format, int plane_type, int width, int height,
                             unsigned int *size) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_size) {
    result = LINK_camera_get_plane_size(GetCameraPixelFormat(format), GetCamxPlaneType(plane_type),
                                        width, height, size);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane size. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneSize. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetCameraFormatPlaneInfo(int format, int width, int height, int *plane_count,
                                         PlaneLayoutInfo *plane_info) {
  int h_subsampling = 0;
  int v_subsampling = 0;
  int offset = 0;
  int pixel_increment = 0;
  float stride_pixel = 0;
  int stride_bytes = 0;
  int scanlines = 0;
  unsigned int plane_size = 0;
  PlaneComponent plane_type[8] = {};
  int result;
  result = GetPlaneTypes(format, plane_type, plane_count);
  if (result != 0) {
    ALOGE("%s: Failed to get the plane types. Error code : %d", __FUNCTION__, result);
    return result;
  }

  for (int i = 0; i < *plane_count; i++) {
    plane_info[i].component = plane_type[i];
    result = GetSubsamplingFactor(format, plane_type[i], true, &h_subsampling);
    if (result != 0) {
      ALOGE("%s: Failed to get horizontal subsampling factor. plane_type = %d, Error code : %d",
            __FUNCTION__, plane_type[i], result);
      break;
    }
    plane_info[i].h_subsampling = (uint32_t)h_subsampling;

    result = GetSubsamplingFactor(format, plane_type[i], false, &v_subsampling);
    if (result != 0) {
      ALOGE("%s: Failed to get vertical subsampling factor. plane_type = %d, Error code : %d",
            __FUNCTION__, plane_type[i], result);
      break;
    }
    plane_info[i].v_subsampling = (uint32_t)v_subsampling;

    result = GetPlaneOffset(format, plane_type[i], width, height, &offset);
    if (result != 0) {
      ALOGE("%s: Failed to get plane offset. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].offset = (uint32_t)offset;

    result = GetPixelIncrement(format, plane_type[i], &pixel_increment);
    if (result != 0) {
      ALOGE("%s: Failed to get pixel increment. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].step = (int32_t)pixel_increment;

    result = GetStrideInPixels(format, plane_type[i], width, &stride_pixel);
    if (result != 0) {
      ALOGE("%s: Failed to get stride in pixel. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].stride = (int32_t)stride_pixel;

    result = GetStrideInBytes(format, plane_type[i], width, &stride_bytes);
    if (result != 0) {
      ALOGE("%s: Failed to get stride in bytes. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].stride_bytes = (int32_t)stride_bytes;

    result = GetScanline(format, plane_type[i], height, &scanlines);
    if (result != 0) {
      ALOGE("%s: Failed to get scanlines. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].scanlines = (int32_t)scanlines;

    result = GetPlaneSize(format, plane_type[i], width, height, &plane_size);
    if (result != 0) {
      ALOGE("%s: Failed to get plane size. plane_type = %d, Error code : %d", __FUNCTION__,
            plane_type[i], result);
      break;
    }
    plane_info[i].size = (uint32_t)plane_size;
  }

  return result;
}

int CameraInfo::GetUBWCInfo(int format, bool *is_supported, bool *is_pi, int *version) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_ubwc_info) {
    result = LINK_camera_get_ubwc_info(GetCameraPixelFormat(format), is_supported, is_pi, version);
    if (result != 0) {
      ALOGE("%s: Failed to get the UBWC info. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetUBWCInfo. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetPlaneAlignment(int format, int plane_type, unsigned int *alignment) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_alignment) {
    result = LINK_camera_get_plane_alignment(GetCameraPixelFormat(format),
                                             GetCamxPlaneType(plane_type), alignment);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane alignment. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneAlignment. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::IsPerPlaneFdNeeded(int format, bool *is_per_plane_fd_needed) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_is_per_plane_fd_needed) {
    result =
        LINK_camera_is_per_plane_fd_needed(GetCameraPixelFormat(format), is_per_plane_fd_needed);
    if (result != 0) {
      ALOGE("%s: Failed to get per_plane_fd flag. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_IsPerPlaneFdNeeded. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetBpp(int format, int *bpp) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_bpp) {
    result = LINK_camera_get_bpp(GetCameraPixelFormat(format), bpp);
    if (result != 0) {
      ALOGE("%s: Failed to get the bpp. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetBpp. Error code : %d", __FUNCTION__, result);
  }

  return result;
}

int CameraInfo::GetPerPlaneBpp(int format, int plane_type, int *bpp) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_per_plane_bpp) {
    result = LINK_camera_get_per_plane_bpp(GetCameraPixelFormat(format),
                                           GetCamxPlaneType(plane_type), bpp);
    if (result != 0) {
      ALOGE("%s: Failed to get the per plane bpp. Error code: %d", __FUNCTION__, result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPerPlaneBpp. Error code : %d", __FUNCTION__,
          result);
  }

  return result;
}

int CameraInfo::GetPlaneStartAddressAlignment(int format, int plane_type, int *alignment) {
  CamxFormatResult result = (CamxFormatResult)-1;
  if (LINK_camera_get_plane_start_address_alignment) {
    result = LINK_camera_get_plane_start_address_alignment(GetCameraPixelFormat(format),
                                                           GetCamxPlaneType(plane_type), alignment);
    if (result != 0) {
      ALOGE("%s: Failed to get the plane star address alignment. Error code: %d", __FUNCTION__,
            result);
    }
  } else {
    ALOGW("%s: Failed to link CamxFormatUtil_GetPlaneStartAddressAlignment. Error code : %d",
          __FUNCTION__, result);
  }

  return result;
}

PlaneComponent CameraInfo::GetPlaneComponent(CamxPlaneType plane_type) {
  PlaneComponent plane_component = (PlaneComponent)0;
  switch (plane_type) {
    case CAMERA_PLANE_TYPE_RAW:
      plane_component = (PlaneComponent)PLANE_COMPONENT_RAW;
      break;
    case CAMERA_PLANE_TYPE_Y:
      plane_component = (PlaneComponent)PLANE_COMPONENT_Y;
      break;
    case CAMERA_PLANE_TYPE_UV:
      plane_component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
      break;
    case CAMERA_PLANE_TYPE_U:
      plane_component = (PlaneComponent)PLANE_COMPONENT_Cb;
      break;
    case CAMERA_PLANE_TYPE_V:
      plane_component = (PlaneComponent)PLANE_COMPONENT_Cr;
      break;
    case CAMERA_PLANE_TYPE_META_Y:
      plane_component = (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Y);
      break;
    case CAMERA_PLANE_TYPE_META_VU:
      plane_component =
          (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
      break;
    default:
      ALOGE("%s: No PlaneComponent mapping for plane_type: %d", __FUNCTION__, plane_type);
      break;
  }

  return plane_component;
}

CamxPlaneType CameraInfo::GetCamxPlaneType(int plane_type) {
  CamxPlaneType camx_plane_type = (CamxPlaneType)0;
  switch (plane_type) {
    case PLANE_COMPONENT_RAW:
      camx_plane_type = CAMERA_PLANE_TYPE_RAW;
      break;
    case PLANE_COMPONENT_Y:
      camx_plane_type = CAMERA_PLANE_TYPE_Y;
      break;
    case (PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr):
      camx_plane_type = CAMERA_PLANE_TYPE_UV;
      break;
    case PLANE_COMPONENT_Cb:
      camx_plane_type = CAMERA_PLANE_TYPE_U;
      break;
    case PLANE_COMPONENT_Cr:
      camx_plane_type = CAMERA_PLANE_TYPE_V;
      break;
    case (PLANE_COMPONENT_META | PLANE_COMPONENT_Y):
      camx_plane_type = CAMERA_PLANE_TYPE_META_Y;
      break;
    case (PLANE_COMPONENT_META | PLANE_COMPONENT_Cr | PLANE_COMPONENT_Cb):
      camx_plane_type = CAMERA_PLANE_TYPE_META_VU;
      break;
    default:
      ALOGE("%s: No CamxPlane for plane_type: %d", __FUNCTION__, plane_type);
      break;
  }

  return camx_plane_type;
}

}  // namespace gralloc
