/*
* 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.
*/

#ifndef __DRM_PROPERTY_H__
#define __DRM_PROPERTY_H__

#include <stdint.h>
#include <string>
#include <map>
#include <unordered_map>
#include <xf86drmMode.h>

namespace sde_drm {

enum struct DRMProperty {
  INVALID,
  TYPE,
  FB_ID,
  CRTC_ID,
  CRTC_X,
  CRTC_Y,
  CRTC_W,
  CRTC_H,
  SRC_X,
  SRC_Y,
  SRC_W,
  SRC_H,
  ZPOS,
  ALPHA,
  EXCL_RECT,
  H_DECIMATE,
  V_DECIMATE,
  INPUT_FENCE,
  ROTATION,
  BLEND_OP,
  SRC_CONFIG,
  SCALER_V1,
  SCALER_V2,
  CSC_V1,
  CAPABILITIES,
  MODE_PROPERTIES,
  LUT_ED,
  LUT_CIR,
  LUT_SEP,
  ROTATOR_CAPS_V1,
  TRUE_INLINE_ROT_REV,
  FB_TRANSLATION_MODE,
  ACTIVE,
  MODE_ID,
  OUTPUT_FENCE_OFFSET,
  OUTPUT_FENCE,
  ROI_V1,
  CORE_CLK,
  CORE_AB,
  CORE_IB,
  LLCC_AB,
  LLCC_IB,
  DRAM_AB,
  DRAM_IB,
  ROT_PREFILL_BW,
  ROT_CLK,
  SECURITY_LEVEL,
  DIM_STAGES_V1,
  IDLE_TIME,
  RETIRE_FENCE,
  DST_X,
  DST_Y,
  DST_W,
  DST_H,
  LP,
  HDR_PROPERTIES,
  DEST_SCALER,
  DS_LUT_ED,
  DS_LUT_CIR,
  DS_LUT_SEP,
  SDE_DSPP_GAMUT_V3,
  SDE_DSPP_GAMUT_V4,
  SDE_DSPP_GAMUT_V5,
  SDE_DSPP_GC_V1,
  SDE_DSPP_GC_V2,
  SDE_DSPP_IGC_V2,
  SDE_DSPP_IGC_V3,
  SDE_DSPP_IGC_V4,
  SDE_DSPP_PCC_V3,
  SDE_DSPP_PCC_V4,
  SDE_DSPP_PCC_V5,
  SDE_DSPP_PA_HSIC_V1,
  SDE_DSPP_PA_HSIC_V2,
  SDE_DSPP_PA_SIXZONE_V1,
  SDE_DSPP_PA_SIXZONE_V2,
  SDE_DSPP_PA_MEMCOL_SKIN_V1,
  SDE_DSPP_PA_MEMCOL_SKIN_V2,
  SDE_DSPP_PA_MEMCOL_SKY_V1,
  SDE_DSPP_PA_MEMCOL_SKY_V2,
  SDE_DSPP_PA_MEMCOL_FOLIAGE_V1,
  SDE_DSPP_PA_MEMCOL_FOLIAGE_V2,
  SDE_DSPP_PA_MEMCOL_PROT_V1,
  SDE_DSPP_PA_MEMCOL_PROT_V2,
  AUTOREFRESH,
  EXT_HDR_PROPERTIES,
  HDR_METADATA,
  MULTIRECT_MODE,
  ROT_FB_ID,
  SDE_DSPP_PA_DITHER_V1,
  SDE_DSPP_PA_DITHER_V2,
  SDE_PP_DITHER_V1,
  SDE_PP_DITHER_V2,
  INVERSE_PMA,
  CSC_DMA_V1,
  SDE_DGM_1D_LUT_IGC_V5,
  SDE_DGM_1D_LUT_GC_V5,
  SDE_VIG_1D_LUT_IGC_V5,
  SDE_VIG_1D_LUT_IGC_V6,
  SDE_VIG_3D_LUT_GAMUT_V5,
  SDE_VIG_3D_LUT_GAMUT_V6,
  SDE_DSPP_AD4_MODE,
  SDE_DSPP_AD4_INIT,
  SDE_DSPP_AD4_CFG,
  SDE_DSPP_AD4_INPUT,
  SDE_DSPP_AD4_BACKLIGHT,
  SDE_DSPP_AD4_ROI,
  SDE_DSPP_AD4_ASSERTIVENESS,
  SDE_DSPP_AD4_STRENGTH,
  SDE_DSPP_ABA_HIST_CTRL,
  SDE_DSPP_ABA_HIST_IRQ,
  SDE_DSPP_ABA_LUT,
  SDE_DSPP_SV_BL_SCALE,
  SDE_DSPP_BL_SCALE,
  CAPTURE_MODE,
  QSYNC_MODE,
  IDLE_PC_STATE,
  TOPOLOGY_CONTROL,
  EDID,
  SDE_LTM_VERSION,
  SDE_LTM_INIT,
  SDE_LTM_CFG,
  SDE_LTM_NOISE_THRESH,
  SDE_LTM_HIST_CTRL,
  SDE_LTM_BUFFER_CTRL,
  SDE_LTM_QUEUE_BUFFER,
  SDE_LTM_QUEUE_BUFFER2,
  SDE_LTM_QUEUE_BUFFER3,
  SDE_LTM_VLUT,
  FRAME_TRIGGER,
  COLORSPACE,
  SUPPORTED_COLORSPACES,
  SDE_SSPP_LAYOUT,

  // Insert above
  MAX
};

struct DRMPropertyManager {
  DRMProperty GetPropertyEnum(const std::string &name) const;

  void SetPropertyId(DRMProperty prop_enum, uint32_t prop_id) {
    properties_[(uint32_t)prop_enum] = prop_id;
  }

  uint32_t GetPropertyId(DRMProperty prop_enum) const {
    return properties_[(uint32_t)prop_enum];
  }

  bool IsPropertyAvailable(DRMProperty prop_enum) const {
    return !!properties_[(uint32_t)prop_enum];
  }

 private:
  uint32_t properties_[(uint32_t)DRMProperty::MAX] {};
};

struct DRMObject {
  virtual ~DRMObject() = default;
  virtual uint32_t GetObjectId() = 0;
  void Dump() {};

  void AddProperty(DRMProperty prop, uint64_t value, bool force_dirty = false);
  void RemoveProperty(DRMProperty prop);
  size_t ApplyDirtyProperties(drmModeAtomicReq *req);
  void DiscardDirtyProperties() { dirty_values_.clear(); }
  void ClearProperties();
  void CommitProperties();

 protected:
  explicit DRMObject(DRMPropertyManager &pm);

 private:
  std::unordered_map<uint32_t, uint64_t> property_values_ {};
  // store properties ordered by prop_id to avoid re-sort in libdrm
  std::map<uint32_t, uint64_t, std::greater<uint32_t>> dirty_values_ {};
  DRMPropertyManager& property_manager_;
};

template<class T>
struct DRMObjectManager {
  virtual ~DRMObjectManager() = default;
  void DumpById(uint32_t id) { object_pool_.at(id)->Dump(); }
  void DumpAll() {
    for (auto &obj : object_pool_)
      obj.second->Dump();
  }

  size_t ApplyDirtyProperties(drmModeAtomicReq *req) {
    size_t dirty_count = 0;
    for (auto &obj : object_pool_)
      dirty_count += obj.second->ApplyDirtyProperties(req);

    return dirty_count;
  }

  void ClearProperties() {
    for (auto &obj : object_pool_)
      obj.second->ClearProperties();
  }

  T* GetObject(uint32_t obj_id) {
    auto it = object_pool_.find(obj_id);
    if (it == object_pool_.end())
      return nullptr;
    return it->second.get();
  }
 protected:
  // store objects ordered by obj_id to avoid re-sort in libdrm
  std::map<uint32_t, std::unique_ptr<T>> object_pool_{};
};

}  // namespace sde_drm

#endif  // __DRM_PROPERTY_H__
