#include "irc/parse_caps.hpp"

const std::unordered_map<std::string, std::optional<std::string>>
parse_caps(const std::string &caps) {
  std::unordered_map<std::string, std::optional<std::string>> output;
  // caps => multi-prefix sasl=PLAIN,EXTERNAL
  //   draft/multiline=max-bytes=40000,max-lines=10
  const std::vector<std::string> &caps_list = utils::split(caps, ' ', false);
  for (const std::string &cap : caps_list) {
    // cap => multi-prefix
    // cap => sasl=PLAIN,EXTERNAL
    // cap => draft/multiline=max-bytes=40000,max-lines=10
    const size_t delimiter = cap.find("=");
    // delimiter(multi-prefix) => npos
    // delimiter(sasl=PLAIN,EXTERNAL) => 5
    // delimiter(draft/multiline=max-bytes=40000,max-lines=10) => 16
    const std::string cap_name = cap.substr(0, delimiter);
    std::optional<std::string> cap_value;
    if (delimiter != std::string::npos)
      cap_value = cap.substr(delimiter + 1);
    output.insert_or_assign(cap_name, cap_value);
  }

  return output;
}

const std::vector<std::string> parse_cap_val_list(const std::string &value) {
  // value(PLAIN,EXTERNAL) => PLAIN,EXTERNAL
  return utils::split(value, ',', false);
}

const std::unordered_map<std::string, std::optional<std::string>>
parse_cap_keyval(const std::string &value) {
  std::unordered_map<std::string, std::optional<std::string>> output;
  // value(PLAIN,EXTERNAL) => PLAIN,EXTERNAL
  // value(max-bytes=40000,max-lines=10) =>
  //   max-bytes=40000,max-lines=10
  const std::vector<std::string> &values_list = utils::split(value, ',', false);
  // values_list(PLAIN,EXTERNAL) => { "PLAIN", "EXTERNAL" }
  // values_list(draft/multiline=max-bytes=40000,max-lines=10) => {
  //   "max-bytes=40000", "max-lines=10" }
  for (const std::string &value : values_list) {
    const size_t value_delimiter = value.find("=");
    // key(PLAIN) => PLAIN
    // key(max-bytes=40000) => max-bytes
    const std::string key = value.substr(0, value_delimiter);
    std::optional<std::string> val;
    if (value_delimiter != std::string::npos) {
      // val(max-bytes=40000) => 40000
      val = value.substr(value_delimiter + 1);
    }
    output.insert_or_assign(key, val);
  }

  return output;
}
