/*
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 * Not a Contribution.
 *
 * Copyright (C) 2017 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.
 */

#ifndef __QTICOMPOSERCOMMANDBUFFER_H__
#define __QTICOMPOSERCOMMANDBUFFER_H__

#include <log/log.h>
#include <sync/sync.h>
#include <fmq/MessageQueue.h>
#include <hidl/MQDescriptor.h>
#include <utils/fence.h>

#include <limits>
#include <algorithm>
#include <vector>
#include <string>

namespace vendor {
namespace qti {
namespace hardware {
namespace display {
namespace composer {
namespace V3_0 {

using ::android::hardware::graphics::common::V1_0::ColorTransform;
using ::android::hardware::graphics::common::V1_0::Dataspace;
using ::android::hardware::graphics::common::V1_0::Transform;
using ::android::hardware::graphics::composer::V2_1::Error;
using ::android::hardware::graphics::composer::V2_1::Display;
using ::android::hardware::graphics::composer::V2_1::Layer;
using ::android::hardware::MessageQueue;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::hidl_vec;
using ::android::hardware::hidl_handle;

using CommandQueueType = MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite>;

using std::shared_ptr;
using std::string;
using sdm::Fence;

// This class helps build a command queue.  Note that all sizes/lengths are in units of uint32_t's.
class CommandWriter {
 public:
  explicit CommandWriter(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
    mData = std::make_unique<uint32_t[]>(mDataMaxSize);
    reset();
  }

  ~CommandWriter() { reset(); }

  void reset() {
    mDataWritten = 0;
    mCommandEnd = 0;

    // handles in mDataHandles are owned by the caller
    mDataHandles.clear();

    // handles in mTemporaryHandles are owned by the writer
    for (auto handle : mTemporaryHandles) {
      native_handle_close(handle);
      native_handle_delete(handle);
    }
    mTemporaryHandles.clear();
  }

  IQtiComposerClient::Command getCommand(uint32_t offset) {
    uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
    return static_cast<IQtiComposerClient::Command>(val &
      static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK));
  }

  bool writeQueue(bool& queueChanged, uint32_t& commandLength,
                  hidl_vec<hidl_handle>& commandHandles) {
    if (mDataWritten == 0) {
      queueChanged = false;
      commandLength = 0;
      commandHandles.setToExternal(nullptr, 0);
      return true;
    }

    // After data are written to the queue, it may not be read by the
    // remote reader when
    //
    //  - the writer does not send them (because of other errors)
    //  - the hwbinder transaction fails
    //  - the reader does not read them (because of other errors)
    //
    // Discard the stale data here.
    size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
    if (staleDataSize > 0) {
      ALOGW("discarding stale data from message queue");
      CommandQueueType::MemTransaction tx;
      if (mQueue->beginRead(staleDataSize, &tx)) {
        mQueue->commitRead(staleDataSize);
      }
    }
    // write data to queue, optionally resizing it
    if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
      if (!mQueue->write(mData.get(), mDataWritten)) {
        ALOGE("failed to write commands to message queue");
        return false;
      }

      queueChanged = false;
    } else {
      auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
      if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
        ALOGE("failed to prepare a new message queue ");
        return false;
      }

      mQueue = std::move(newQueue);
      queueChanged = true;
    }

    commandLength = mDataWritten;
    commandHandles.setToExternal(const_cast<hidl_handle*>(mDataHandles.data()),
                                 mDataHandles.size());

    return true;
  }

  const MQDescriptorSync<uint32_t>* getMQDescriptor() const {
    return (mQueue) ? mQueue->getDesc() : nullptr;
  }

  // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
  static constexpr uint16_t kSelectDisplayLength = 2;
  void selectDisplay(Display display) {
    beginCommand(IQtiComposerClient::Command::SELECT_DISPLAY, kSelectDisplayLength);
    write64(display);
    endCommand();
  }

  static constexpr uint16_t kSelectLayerLength = 2;
  void selectLayer(Layer layer) {
    beginCommand(IQtiComposerClient::Command::SELECT_LAYER, kSelectLayerLength);
    write64(layer);
    endCommand();
  }

  static constexpr uint16_t kSetErrorLength = 2;
  void setError(uint32_t location, Error error) {
    beginCommand(IQtiComposerClient::Command::SET_ERROR, kSetErrorLength);
    write(location);
    writeSigned(static_cast<int32_t>(error));
    endCommand();
  }

  static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
  void setPresentOrValidateResult(uint32_t state) {
    beginCommand(IQtiComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
                 kPresentOrValidateDisplayResultLength);
    write(state);
    endCommand();
  }

  void setChangedCompositionTypes(const std::vector<Layer>& layers,
                                  const std::vector<IQtiComposerClient::Composition>& types) {
    size_t totalLayers = std::min(layers.size(), types.size());
    size_t currentLayer = 0;

    while (currentLayer < totalLayers) {
      size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);

      beginCommand(IQtiComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
      for (size_t i = 0; i < count; i++) {
        write64(layers[currentLayer + i]);
        writeSigned(static_cast<int32_t>(types[currentLayer + i]));
      }
      endCommand();

      currentLayer += count;
    }
  }

  void setDisplayRequests(uint32_t displayRequestMask, const std::vector<Layer>& layers,
                          const std::vector<uint32_t>& layerRequestMasks) {
    size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
    size_t currentLayer = 0;

    while (currentLayer < totalLayers) {
      size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);

      beginCommand(IQtiComposerClient::Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
      write(displayRequestMask);
      for (size_t i = 0; i < count; i++) {
        write64(layers[currentLayer + i]);
        write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
      }
      endCommand();

      currentLayer += count;
    }
  }

  static constexpr uint16_t kSetPresentFenceLength = 1;
  void setPresentFence(const shared_ptr<Fence> &presentFence) {
    beginCommand(IQtiComposerClient::Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
    writeFence(presentFence);
    endCommand();
  }

  void setReleaseFences(const std::vector<Layer>& layers,
                        const std::vector<shared_ptr<Fence>>& releaseFences) {
    size_t totalLayers = std::min(layers.size(), releaseFences.size());
    size_t currentLayer = 0;

    while (currentLayer < totalLayers) {
      size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);

      beginCommand(IQtiComposerClient::Command::SET_RELEASE_FENCES, count * 3);
      for (size_t i = 0; i < count; i++) {
        write64(layers[currentLayer + i]);
        writeFence(releaseFences[currentLayer + i]);
      }
      endCommand();

      currentLayer += count;
    }
  }

  static constexpr uint16_t kSetColorTransformLength = 17;
  void setColorTransform(const float* matrix, ColorTransform hint) {
    beginCommand(IQtiComposerClient::Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
    for (int i = 0; i < 16; i++) {
      writeFloat(matrix[i]);
    }
    writeSigned(static_cast<int32_t>(hint));
    endCommand();
  }

  void setClientTarget(uint32_t slot, const native_handle_t* target,
                       const shared_ptr<Fence>& acquireFence, Dataspace dataspace,
                       const std::vector<IQtiComposerClient::Rect>& damage) {
    bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
    size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);

    beginCommand(IQtiComposerClient::Command::SET_CLIENT_TARGET, length);
    write(slot);
    writeHandle(target, true);
    writeFence(acquireFence);
    writeSigned(static_cast<int32_t>(dataspace));
    // When there are too many rectangles in the damage region and doWrite
    // is false, we write no rectangle at all which means the entire
    // client target is damaged.
    if (doWrite) {
      writeRegion(damage);
    }
    endCommand();
  }

  static constexpr uint16_t kSetOutputBufferLength = 3;
  void setOutputBuffer(uint32_t slot, const native_handle_t* buffer,
                       const shared_ptr<Fence>& releaseFence) {
    beginCommand(IQtiComposerClient::Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
    write(slot);
    writeHandle(buffer, true);
    writeFence(releaseFence);
    endCommand();
  }

  static constexpr uint16_t kValidateDisplayLength = 0;
  void validateDisplay() {
    beginCommand(IQtiComposerClient::Command::VALIDATE_DISPLAY, kValidateDisplayLength);
    endCommand();
  }

  static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
  void presentOrvalidateDisplay() {
    beginCommand(IQtiComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
                 kPresentOrValidateDisplayLength);
    endCommand();
  }

  static constexpr uint16_t kAcceptDisplayChangesLength = 0;
  void acceptDisplayChanges() {
    beginCommand(IQtiComposerClient::Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
    endCommand();
  }

  static constexpr uint16_t kPresentDisplayLength = 0;
  void presentDisplay() {
    beginCommand(IQtiComposerClient::Command::PRESENT_DISPLAY, kPresentDisplayLength);
    endCommand();
  }

  static constexpr uint16_t kSetLayerCursorPositionLength = 2;
  void setLayerCursorPosition(int32_t x, int32_t y) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_CURSOR_POSITION,
                 kSetLayerCursorPositionLength);
    writeSigned(x);
    writeSigned(y);
    endCommand();
  }

  static constexpr uint16_t kSetLayerBufferLength = 3;
  void setLayerBuffer(uint32_t slot, const native_handle_t* buffer,
                      const shared_ptr<Fence>& acquireFence) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
    write(slot);
    writeHandle(buffer, true);
    writeFence(acquireFence);
    endCommand();
  }

  void setLayerSurfaceDamage(const std::vector<IQtiComposerClient::Rect>& damage) {
    bool doWrite = (damage.size() <= kMaxLength / 4);
    size_t length = (doWrite) ? damage.size() * 4 : 0;

    beginCommand(IQtiComposerClient::Command::SET_LAYER_SURFACE_DAMAGE, length);
    // When there are too many rectangles in the damage region and doWrite
    // is false, we write no rectangle at all which means the entire
    // layer is damaged.
    if (doWrite) {
      writeRegion(damage);
    }
    endCommand();
  }

  static constexpr uint16_t kSetLayerBlendModeLength = 1;
  void setLayerBlendMode(IQtiComposerClient::BlendMode mode) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
    writeSigned(static_cast<int32_t>(mode));
    endCommand();
  }

  static constexpr uint16_t kSetLayerColorLength = 1;
  void setLayerColor(IQtiComposerClient::Color color) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR, kSetLayerColorLength);
    writeColor(color);
    endCommand();
  }

  static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
  void setLayerCompositionType(IQtiComposerClient::Composition type) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_COMPOSITION_TYPE,
                 kSetLayerCompositionTypeLength);
    writeSigned(static_cast<int32_t>(type));
    endCommand();
  }

  static constexpr uint16_t kSetLayerDataspaceLength = 1;
  void setLayerDataspace(Dataspace dataspace) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
    writeSigned(static_cast<int32_t>(dataspace));
    endCommand();
  }

  static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
  void setLayerDisplayFrame(const IQtiComposerClient::Rect& frame) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
    writeRect(frame);
    endCommand();
  }

  static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
  void setLayerPlaneAlpha(float alpha) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
    writeFloat(alpha);
    endCommand();
  }

  static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
  void setLayerSidebandStream(const native_handle_t* stream) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_SIDEBAND_STREAM,
                 kSetLayerSidebandStreamLength);
    writeHandle(stream);
    endCommand();
  }

  static constexpr uint16_t kSetLayerSourceCropLength = 4;
  void setLayerSourceCrop(const IQtiComposerClient::FRect& crop) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
    writeFRect(crop);
    endCommand();
  }

  static constexpr uint16_t kSetLayerTransformLength = 1;
  void setLayerTransform(Transform transform) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
    writeSigned(static_cast<int32_t>(transform));
    endCommand();
  }

  void setLayerVisibleRegion(const std::vector<IQtiComposerClient::Rect>& visible) {
    bool doWrite = (visible.size() <= kMaxLength / 4);
    size_t length = (doWrite) ? visible.size() * 4 : 0;

    beginCommand(IQtiComposerClient::Command::SET_LAYER_VISIBLE_REGION, length);
    // When there are too many rectangles in the visible region and
    // doWrite is false, we write no rectangle at all which means the
    // entire layer is visible.
    if (doWrite) {
      writeRegion(visible);
    }
    endCommand();
  }

  static constexpr uint16_t kSetLayerZOrderLength = 1;
  void setLayerZOrder(uint32_t z) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
    write(z);
    endCommand();
  }

  static constexpr uint16_t kSetLayerTypeLength = 1;
  void setLayerType(uint32_t z) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_TYPE, kSetLayerTypeLength);
    write(z);
    endCommand();
  }

  // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
  static constexpr uint16_t kSetLayerFloatColorLength = 4;
  void setLayerFloatColor(IQtiComposerClient::FloatColor color) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
    writeFloatColor(color);
    endCommand();
  }

  void setLayerPerFrameMetadata(const hidl_vec<IQtiComposerClient::PerFrameMetadata>& metadataVec) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
                 metadataVec.size() * 2);
    for (const auto& metadata : metadataVec) {
      writeSigned(static_cast<int32_t>(metadata.key));
      writeFloat(metadata.value);
    }
    endCommand();
  }

  // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
  static constexpr uint16_t kSetLayerColorTransformLength = 16;
  void setLayerColorTransform(const float* matrix) {
    beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR_TRANSFORM,
                 kSetLayerColorTransformLength);
    for (int i = 0; i < 16; i++) {
      writeFloat(matrix[i]);
    }
    endCommand();
  }

  void setLayerPerFrameMetadataBlobs(
    const hidl_vec<IQtiComposerClient::PerFrameMetadataBlob>& metadata) {
    size_t commandLength = 0;

    if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
      LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
      return;
    }

    // number of blobs
    commandLength += metadata.size();

    for (auto metadataBlob : metadata) {
      commandLength += sizeof(int32_t);  // key of metadata blob
      commandLength += 1;                // size information of metadata blob

      // metadata content size
      size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
      commandLength += metadataSize;
      commandLength += (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
    }

    if (commandLength > std::numeric_limits<uint16_t>::max()) {
      LOG_FATAL("dynamic metadata size is too large");
      return;
    }

    // Blobs are written as:
    // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
    uint16_t length = static_cast<uint16_t>(commandLength);
    beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
    write(static_cast<uint32_t>(metadata.size()));
    for (auto metadataBlob : metadata) {
      writeSigned(static_cast<int32_t>(metadataBlob.key));
      write(static_cast<uint32_t>(metadataBlob.blob.size()));
      writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
    }
    endCommand();
  }

  static constexpr uint16_t kSetDisplayElapseTime = 2;
  void setDisplayElapseTime(uint64_t time) {
    beginCommand(IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME, kSetDisplayElapseTime);
    write64(time);
    endCommand();
  }

 protected:
  // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
  void beginCommand(IQtiComposerClient::Command command, uint16_t length) {
    if (mCommandEnd) {
      LOG_FATAL("endCommand was not called before command 0x%x", command);
    }

    growData(1 + length);
    write(static_cast<uint32_t>(command) | length);

    mCommandEnd = mDataWritten + length;
  }

  void endCommand() {
    if (!mCommandEnd) {
      LOG_FATAL("beginCommand was not called");
    } else if (mDataWritten > mCommandEnd) {
      LOG_FATAL("too much data written");
      mDataWritten = mCommandEnd;
    } else if (mDataWritten < mCommandEnd) {
      LOG_FATAL("too little data written");
      while (mDataWritten < mCommandEnd) {
        write(0);
      }
    }

    mCommandEnd = 0;
  }

  void write(uint32_t val) { mData[mDataWritten++] = val; }

  void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }

  void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }

  void write64(uint64_t val) {
    uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
    uint32_t hi = static_cast<uint32_t>(val >> 32);
    write(lo);
    write(hi);
  }

  void writeRect(const IQtiComposerClient::Rect& rect) {
    writeSigned(rect.left);
    writeSigned(rect.top);
    writeSigned(rect.right);
    writeSigned(rect.bottom);
  }

  void writeRegion(const std::vector<IQtiComposerClient::Rect>& region) {
    for (const auto& rect : region) {
      writeRect(rect);
    }
  }

  void writeFRect(const IQtiComposerClient::FRect& rect) {
    writeFloat(rect.left);
    writeFloat(rect.top);
    writeFloat(rect.right);
    writeFloat(rect.bottom);
  }

  void writeColor(const IQtiComposerClient::Color& color) {
    write((color.r <<  0) | (color.g <<  8) | (color.b << 16) | (color.a << 24));
  }

  // ownership of handle is not transferred
  void writeHandle(const native_handle_t* handle, bool useCache) {
    if (!handle) {
      writeSigned(static_cast<int32_t>((useCache) ?
                IQtiComposerClient::HandleIndex::CACHED : IQtiComposerClient::HandleIndex::EMPTY));
      return;
    }

    mDataHandles.push_back(handle);
    writeSigned(mDataHandles.size() - 1);
  }

  void writeHandle(const native_handle_t* handle) {
    writeHandle(handle, false);
  }

  // Handle would own fence hereafter. Hence provide a dupped fd.
  void writeFence(const shared_ptr<Fence>& fence) {
    native_handle_t* handle = nullptr;
    if (fence) {
      handle = getTemporaryHandle(1, 0);
      if (handle) {
        handle->data[0] = Fence::Dup(fence);
      } else {
        ALOGW("failed to get temporary handle for fence %s", Fence::GetStr(fence).c_str());
        Fence::Wait(fence);
      }
    }

    writeHandle(handle);
  }

  native_handle_t* getTemporaryHandle(int numFds, int numInts) {
    native_handle_t* handle = native_handle_create(numFds, numInts);
    if (handle) {
      mTemporaryHandles.push_back(handle);
    }
    return handle;
  }

  static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();

  // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
  void writeFloatColor(const IQtiComposerClient::FloatColor& color) {
    writeFloat(color.r);
    writeFloat(color.g);
    writeFloat(color.b);
    writeFloat(color.a);
  }

  // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
  void writeBlob(uint32_t length, const unsigned char* blob) {
    memcpy(&mData[mDataWritten], blob, length);
    uint32_t numElements = length / 4;
    mDataWritten += numElements;
    mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
  }

 private:
  void growData(uint32_t grow) {
    uint32_t newWritten = mDataWritten + grow;
    if (newWritten < mDataWritten) {
      LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32
                       ", growing by %" PRIu32, mDataWritten, grow);
    }

    if (newWritten <= mDataMaxSize) {
      return;
    }

    uint32_t newMaxSize = mDataMaxSize << 1;
    if (newMaxSize < newWritten) {
      newMaxSize = newWritten;
    }

    auto newData = std::make_unique<uint32_t[]>(newMaxSize);
    std::copy_n(mData.get(), mDataWritten, newData.get());
    mDataMaxSize = newMaxSize;
    mData = std::move(newData);
  }

  uint32_t mDataMaxSize;
  std::unique_ptr<uint32_t[]> mData;

  uint32_t mDataWritten;
  // end offset of the current command
  uint32_t mCommandEnd;

  std::vector<hidl_handle> mDataHandles;
  std::vector<native_handle_t *> mTemporaryHandles;

  std::unique_ptr<CommandQueueType> mQueue;
};

// This class helps parse a command queue.  Note that all sizes/lengths are in units of uint32_t's.
class CommandReaderBase {
 public:
  CommandReaderBase() : mDataMaxSize(0) { reset(); }

  bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
    mQueue = std::make_unique<CommandQueueType>(descriptor, false);
    if (mQueue->isValid()) {
      return true;
    } else {
      mQueue = nullptr;
      return false;
    }
  }

  bool readQueue(uint32_t commandLength, const hidl_vec<hidl_handle>& commandHandles) {
    if (!mQueue) {
      return false;
    }

    auto quantumCount = mQueue->getQuantumCount();
    if (mDataMaxSize < quantumCount) {
      mDataMaxSize = quantumCount;
      mData = std::make_unique<uint32_t[]>(mDataMaxSize);
    }

    if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
      ALOGE("failed to read commands from message queue");
      return false;
    }

    mDataSize = commandLength;
    mDataRead = 0;
    mCommandBegin = 0;
    mCommandEnd = 0;
    mDataHandles.setToExternal(const_cast<hidl_handle*>(commandHandles.data()),
                               commandHandles.size());

    return true;
  }

  void reset() {
    mDataSize = 0;
    mDataRead = 0;
    mCommandBegin = 0;
    mCommandEnd = 0;
    mDataHandles.setToExternal(nullptr, 0);
  }

 protected:
  bool isEmpty() const { return (mDataRead >= mDataSize); }

  bool beginCommand(IQtiComposerClient::Command& command, uint16_t& length) {
    if (mCommandEnd) {
      LOG_FATAL("endCommand was not called before command 0x%x", command);
    }

    constexpr uint32_t opcode_mask =
      static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK);
    constexpr uint32_t length_mask =
      static_cast<uint32_t>(IQtiComposerClient::Command::LENGTH_MASK);

    uint32_t val = read();
    command = static_cast<IQtiComposerClient::Command>(val & opcode_mask);
    length = static_cast<uint16_t>(val & length_mask);

    if (mDataRead + length > mDataSize) {
      ALOGE("command 0x%x has invalid command length %" PRIu16, command, length);
      // undo the read() above
      mDataRead--;
      return false;
    }

    mCommandEnd = mDataRead + length;

    return true;
  }

  void endCommand() {
    if (!mCommandEnd) {
      LOG_FATAL("beginCommand was not called");
    } else if (mDataRead > mCommandEnd) {
      LOG_FATAL("too much data read");
      mDataRead = mCommandEnd;
    } else if (mDataRead < mCommandEnd) {
      LOG_FATAL("too little data read");
      mDataRead = mCommandEnd;
    }

    mCommandBegin = mCommandEnd;
    mCommandEnd = 0;
  }

  uint32_t getCommandLoc() const { return mCommandBegin; }

  uint32_t read() { return mData[mDataRead++]; }

  int32_t readSigned() {
    int32_t val;
    memcpy(&val, &mData[mDataRead++], sizeof(val));
    return val;
  }

  float readFloat() {
    float val;
    memcpy(&val, &mData[mDataRead++], sizeof(val));
    return val;
  }

  uint64_t read64() {
    uint32_t lo = read();
    uint32_t hi = read();
    return (static_cast<uint64_t>(hi) << 32) | lo;
  }

  void readBlob(uint32_t size, void* blob) {
    memcpy(blob, &mData[mDataRead], size);
    uint32_t numElements = size / sizeof(uint32_t);
    mDataRead += numElements;
    mDataRead += (size - numElements * sizeof(uint32_t) != 0) ? 1 : 0;
  }

  IQtiComposerClient::Color readColor() {
    uint32_t val = read();
    return IQtiComposerClient::Color{
      static_cast<uint8_t>((val >>  0) & 0xff),
      static_cast<uint8_t>((val >>  8) & 0xff),
      static_cast<uint8_t>((val >> 16) & 0xff),
      static_cast<uint8_t>((val >> 24) & 0xff),
    };
  }

  // ownership of handle is not transferred
  const native_handle_t* readHandle(bool& useCache) {
    const native_handle_t* handle = nullptr;

    int32_t index = readSigned();
    switch (index) {
    case static_cast<int32_t>(IQtiComposerClient::HandleIndex::EMPTY):
      useCache = false;
      break;
    case static_cast<int32_t>(IQtiComposerClient::HandleIndex::CACHED):
      useCache = true;
      break;
    default:
      if (static_cast<size_t>(index) < mDataHandles.size()) {
        handle = mDataHandles[index].getNativeHandle();
      } else {
        ALOGE("invalid handle index %zu", static_cast<size_t>(index));
      }
      useCache = false;
      break;
    }

    return handle;
  }

  const native_handle_t* readHandle() {
    bool useCache;
    return readHandle(useCache);
  }

  // Handle would still own original fence. Hence create a Fence object on duped fd.
  void readFence(shared_ptr<Fence>* fence, const string &name) {
    auto handle = readHandle();
    if (!handle || handle->numFds == 0) {
      return;
    }

    if (handle->numFds != 1) {
      ALOGE("invalid fence handle with %d fds", handle->numFds);
      return;
    }

    *fence = Fence::Create(dup(handle->data[0]), name);
    if (*fence == nullptr) {
      ALOGW("failed to dup fence %d", handle->data[0]);
      sync_wait(handle->data[0], -1);
    }
  }

 private:
  std::unique_ptr<CommandQueueType> mQueue;
  uint32_t mDataMaxSize;
  std::unique_ptr<uint32_t[]> mData;

  uint32_t mDataSize;
  uint32_t mDataRead;

  // begin/end offsets of the current command
  uint32_t mCommandBegin;
  uint32_t mCommandEnd;

  hidl_vec<hidl_handle> mDataHandles;
};

}  // namespace V3_0
}  // namespace composer
}  // namespace display
}  // namespace hardware
}  // namespace qti
}  // namespace vendor

#endif  // __QTICOMPOSERCOMMANDBUFFER_H__
