/*
* 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 <drm/drm_fourcc.h>
#include <drm_utils.h>
#include <regex>
#include <sstream>
#include <sstream>
#include <string>
#include <string>
#include <utility>
#include <vector>

using std::string;
using std::stringstream;
using std::regex;
using std::pair;
using std::vector;

namespace sde_drm {

void ParseFormats(const string &line, vector<pair<uint32_t, uint64_t>> *formats) {
  // Match fourcc strings like RA24 or those with modifier like RA24/5/1. The
  // digit after first / is vendor code, the digit after second / is modifier
  // code.
  regex exp_base("[[:alnum:]]{4}(/[[:digit:]]/([[:digit:]]){1,3})?");
  regex exp_modifier("[[:alnum:]]{4}(/[[:digit:]]/([[:digit:]]){1,3})");
  string tmp_line = line;
  std::smatch str_match;  // Resultant match
  while (std::regex_search(tmp_line, str_match, exp_base)) { //clang_sa_ignore[core.CallAndMessage]
    string matched_sub_str = str_match.str();
    string final_format_str = {};
    uint64_t modifier = 0;

    if (std::regex_match(matched_sub_str, exp_modifier)) { //clang_sa_ignore[core.CallAndMessage]
      // Here we try to parse formats with vendor code and modifier like
      // RA24/5/1

      // Extract base format string
      final_format_str = matched_sub_str.substr(0, matched_sub_str.find("/"));

      // Match vendor code
      string vendor_sub_str = matched_sub_str.substr(matched_sub_str.find("/") + 1);
      uint64_t vendor_code = std::stoi(vendor_sub_str);

      // Match modifier
      uint64_t fmt_modifier = std::stoi(vendor_sub_str.substr(vendor_sub_str.find("/") + 1));
      if (vendor_code == DRM_FORMAT_MOD_VENDOR_QCOM) {
        // Macro from drm_fourcc.h to form modifier
        modifier = fourcc_mod_code(QCOM, fmt_modifier);
      }

    } else {
      final_format_str = matched_sub_str.c_str();
    }

    // fourcc_code is a macro from drm_fourcc.h to form the format from 4 characters (thus fourcc)
    formats->push_back(std::make_pair(fourcc_code(final_format_str.at(0), final_format_str.at(1),
                                                  final_format_str.at(2), final_format_str.at(3)),
                                      modifier));
    tmp_line = str_match.suffix();
  }
}

void Tokenize(const std::string &str, std::vector<std::string> *tokens, char delim) {
  size_t pos = 0;
  std::string str_temp(str);

  while ((pos = str_temp.find(delim)) != std::string::npos && delim != ' ') {
    str_temp.replace(pos, 1, 1, ' ');
  }

  std::stringstream ss(str_temp);
  while (ss >> str_temp) {
    tokens->push_back(str_temp);
  }
}

void AddProperty(drmModeAtomicReqPtr req, uint32_t object_id, uint32_t property_id, uint64_t value,
                 bool cache, std::unordered_map<uint32_t, uint64_t> &prop_val_map) {
#ifndef SDM_VIRTUAL_DRIVER
  auto it = prop_val_map.find(property_id);
  if (it == prop_val_map.end() || it->second != value)
#endif
    drmModeAtomicAddProperty(req, object_id, property_id, value);
#ifndef SDM_VIRTUAL_DRIVER
  if (cache)
    prop_val_map[property_id] = value;
#endif
}

}  // namespace sde_drm
