// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_GFX_X_XPROTO_UTIL_H_
#define UI_GFX_X_XPROTO_UTIL_H_

#include <cstdint>

#include "base/component_export.h"
#include "ui/gfx/x/connection.h"
#include "ui/gfx/x/future.h"
#include "ui/gfx/x/xproto.h"
#include "ui/gfx/x/xproto_types.h"

namespace x11 {

template <typename T>
Future<void> SendEvent(const T& event,
                       Window target,
                       EventMask mask,
                       Connection* connection = Connection::Get()) {
  static_assert(T::type_id > 0, "T must be an *Event type");
  auto write_buffer = Write(event);
  DCHECK_EQ(write_buffer.GetBuffers().size(), 1ul);
  auto& first_buffer = write_buffer.GetBuffers()[0];
  DCHECK_LE(first_buffer->size(), 32ul);
  std::vector<uint8_t> event_bytes(32);
  memcpy(event_bytes.data(), first_buffer->data(), first_buffer->size());

  SendEventRequest send_event{false, target, mask};
  std::copy(event_bytes.begin(), event_bytes.end(), send_event.event.begin());
  return connection->SendEvent(send_event);
}

template <typename T>
bool GetArrayProperty(Window window,
                      Atom name,
                      std::vector<T>* value,
                      Atom* out_type = nullptr,
                      size_t amount = 0,
                      Connection* connection = Connection::Get()) {
  static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "");

  size_t bytes = amount * sizeof(T);
  // The length field specifies the maximum amount of data we would like the
  // server to give us.  It's specified in units of 4 bytes, so divide by 4.
  // Add 3 before division to round up.
  size_t length = (bytes + 3) / 4;
  using lentype = decltype(GetPropertyRequest::long_length);
  auto response =
      connection
          ->GetProperty(GetPropertyRequest{
              .window = static_cast<Window>(window),
              .property = name,
              .long_length = static_cast<uint32_t>(
                  amount ? length : std::numeric_limits<lentype>::max())})
          .Sync();
  if (!response || response->format != CHAR_BIT * sizeof(T))
    return false;

  DCHECK_EQ(response->format / CHAR_BIT * response->value_len,
            response->value->size());
  value->resize(response->value_len);
  memcpy(value->data(), response->value->data(), response->value->size());
  if (out_type)
    *out_type = response->type;
  return true;
}

template <typename T>
bool GetProperty(Window window,
                 const Atom name,
                 T* value,
                 Connection* connection = Connection::Get()) {
  std::vector<T> values;
  if (!GetArrayProperty(window, name, &values, nullptr, 1, connection) ||
      values.empty()) {
    return false;
  }
  *value = values[0];
  return true;
}

template <typename T>
Future<void> SetArrayProperty(Window window,
                              Atom name,
                              Atom type,
                              const std::vector<T>& values,
                              Connection* connection = Connection::Get()) {
  static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4, "");
  std::vector<uint8_t> data(sizeof(T) * values.size());
  memcpy(data.data(), values.data(), sizeof(T) * values.size());
  return connection->ChangeProperty(
      ChangePropertyRequest{.window = static_cast<Window>(window),
                            .property = name,
                            .type = type,
                            .format = CHAR_BIT * sizeof(T),
                            .data_len = static_cast<uint32_t>(values.size()),
                            .data = base::RefCountedBytes::TakeVector(&data)});
}

template <typename T>
Future<void> SetProperty(Window window,
                         Atom name,
                         Atom type,
                         const T& value,
                         Connection* connection = Connection::Get()) {
  return SetArrayProperty(window, name, type, std::vector<T>{value},
                          connection);
}

COMPONENT_EXPORT(X11)
void DeleteProperty(x11::Window window, x11::Atom name);

COMPONENT_EXPORT(X11)
void SetStringProperty(Window window,
                       Atom property,
                       Atom type,
                       const std::string& value,
                       Connection* connection = Connection::Get());

COMPONENT_EXPORT(X11)
Window CreateDummyWindow(const std::string& name = std::string(),
                         Connection* connection = Connection::Get());

}  // namespace x11

#endif  //  UI_GFX_X_XPROTO_UTIL_H_
