#include "include/private/dvr/display_client.h"

#include <cutils/native_handle.h>
#include <log/log.h>
#include <pdx/default_transport/client_channel.h>
#include <pdx/default_transport/client_channel_factory.h>
#include <pdx/status.h>

#include <mutex>

#include <private/dvr/display_protocol.h>
#include <private/dvr/native_buffer.h>

using android::pdx::ErrorStatus;
using android::pdx::LocalHandle;
using android::pdx::LocalChannelHandle;
using android::pdx::Status;
using android::pdx::Transaction;
using android::pdx::rpc::IfAnyOf;

namespace android {
namespace dvr {
namespace display {

Surface::Surface(LocalChannelHandle channel_handle, int* error)
    : BASE{pdx::default_transport::ClientChannel::Create(
          std::move(channel_handle))} {
  auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
  if (!status) {
    ALOGE("Surface::Surface: Failed to get surface info: %s",
          status.GetErrorMessage().c_str());
    Close(status.error());
    if (error)
      *error = status.error();
  }

  surface_id_ = status.get().surface_id;
  z_order_ = status.get().z_order;
  visible_ = status.get().visible;
}

Surface::Surface(const SurfaceAttributes& attributes, int* error)
    : BASE{pdx::default_transport::ClientChannelFactory::Create(
               DisplayProtocol::kClientPath),
           kInfiniteTimeout} {
  auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
  if (!status) {
    ALOGE("Surface::Surface: Failed to create display surface: %s",
          status.GetErrorMessage().c_str());
    Close(status.error());
    if (error)
      *error = status.error();
  }

  surface_id_ = status.get().surface_id;
  z_order_ = status.get().z_order;
  visible_ = status.get().visible;
}

Status<void> Surface::SetVisible(bool visible) {
  return SetAttributes(
      {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
}

Status<void> Surface::SetZOrder(int z_order) {
  return SetAttributes(
      {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
}

Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
  auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
  if (!status) {
    ALOGE(
        "Surface::SetAttributes: Failed to set display surface "
        "attributes: %s",
        status.GetErrorMessage().c_str());
    return status.error_status();
  }

  // Set the local cached copies of the attributes we care about from the full
  // set of attributes sent to the display service.
  for (const auto& attribute : attributes) {
    const auto& key = attribute.first;
    const auto* variant = &attribute.second;
    bool invalid_value = false;
    switch (key) {
      case SurfaceAttribute::Visible:
        invalid_value =
            !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
        break;
      case SurfaceAttribute::ZOrder:
        invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
        break;
    }

    if (invalid_value) {
      ALOGW(
          "Surface::SetAttributes: Failed to set display surface "
          "attribute %d because of incompatible type: %d",
          key, variant->index());
    }
  }

  return {};
}

Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue() {
  ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
  auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(0);
  if (!status) {
    ALOGE("Surface::CreateQueue: Failed to create queue: %s",
          status.GetErrorMessage().c_str());
    return status.error_status();
  }

  auto producer_queue = ProducerQueue::Import(status.take());
  if (!producer_queue) {
    ALOGE("Surface::CreateQueue: Failed to import producer queue!");
    return ErrorStatus(ENOMEM);
  }

  return {std::move(producer_queue)};
}

Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
    uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
    uint64_t usage, size_t capacity) {
  ALOGD_IF(TRACE,
           "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
           "usage=%" PRIx64 " capacity=%zu",
           width, height, layer_count, format, usage, capacity);
  auto status = CreateQueue();
  if (!status)
    return status.error_status();

  auto producer_queue = status.take();

  ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
  for (size_t i = 0; i < capacity; i++) {
    size_t slot;
    const int ret = producer_queue->AllocateBuffer(width, height, layer_count,
                                                   format, usage, &slot);
    if (ret < 0) {
      ALOGE(
          "Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
          producer_queue->id(), strerror(-ret));
      return ErrorStatus(ENOMEM);
    }
    ALOGD_IF(
        TRACE,
        "Surface::CreateQueue: Allocated buffer at slot=%zu of capacity=%zu",
        slot, capacity);
  }

  return {std::move(producer_queue)};
}

DisplayClient::DisplayClient(int* error)
    : BASE(pdx::default_transport::ClientChannelFactory::Create(
               DisplayProtocol::kClientPath),
           kInfiniteTimeout) {
  if (error)
    *error = Client::error();
}

Status<Metrics> DisplayClient::GetDisplayMetrics() {
  return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
}

Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
    const SurfaceAttributes& attributes) {
  int error;
  if (auto client = Surface::Create(attributes, &error))
    return {std::move(client)};
  else
    return ErrorStatus(error);
}

Status<std::unique_ptr<IonBuffer>> DisplayClient::GetNamedBuffer(
    const std::string& name) {
  auto status = InvokeRemoteMethod<DisplayProtocol::GetNamedBuffer>(name);
  if (!status) {
    ALOGE(
        "DisplayClient::GetNamedBuffer: Failed to get named buffer: name=%s; "
        "error=%s",
        name.c_str(), status.GetErrorMessage().c_str());
    return status.error_status();
  }

  auto ion_buffer = std::make_unique<IonBuffer>();
  auto native_buffer_handle = status.take();
  const int ret = native_buffer_handle.Import(ion_buffer.get());
  if (ret < 0) {
    ALOGE(
        "DisplayClient::GetNamedBuffer: Failed to import named buffer: "
        "name=%s; error=%s",
        name.c_str(), strerror(-ret));
    return ErrorStatus(-ret);
  }

  return {std::move(ion_buffer)};
}

Status<bool> DisplayClient::IsVrAppRunning() {
  return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
}

}  // namespace display
}  // namespace dvr
}  // namespace android
