#include "stringutil.h"

#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/case_conv.hpp>

#include <cstdarg>

std::string strfmt(const char* fmt, ...)
{
 va_list args;

 va_start(args, fmt);
 int size = std::vsnprintf(nullptr, 0, fmt, args);
 va_end(args);

 std::string result(size, ' ');

 va_start(args, fmt);
 std::vsnprintf(result.data(), size + 1, fmt, args);
 va_end(args);

 return result;
}

std::vector<std::string> split(std::string value, const std::string separators)
{
 std::vector<std::string> result;

 size_t pos0 = 0;
 size_t pos1 = 0;
 while (pos0 < value.size()) {
  pos1 = value.find_first_of(separators, pos0);
  if (pos1 == std::string::npos)
   pos1 = value.size();
  std::string part = value.substr(pos0, pos1 - pos0);
  //std::cout << "DEBUG: " << part << std::endl << std::flush;
  if (part != "")
   result.push_back(part);
  pos0 = value.find_first_not_of(separators, pos1);
  if (pos0 == std::string::npos)
   pos0 = value.size();
 }

 return result;
}

std::string join(std::vector<std::string> vs, std::string separator)
{
  std::string s;
  for (const auto& line : vs) {
   if (s.size() > 0)
    s += separator;
   s += line;
  }

  return s;
}

bool startsWithAnyOfLower(const std::string &s, const std::vector<std::string> &list) {
 for (const std::string& element : list) {
  if (boost::algorithm::starts_with(boost::algorithm::to_lower_copy(s), boost::algorithm::to_lower_copy(element)))
   return true;
 }
 return false;
}