/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmQtAutoGen.h"
#include "cmAlgorithms.h"
#include "cmSystemTools.h"

#include "cmsys/RegularExpression.hxx"

#include <algorithm>
#include <iterator>
#include <sstream>

// - Static variables

std::string const genNameGen = "AutoGen";
std::string const genNameMoc = "AutoMoc";
std::string const genNameUic = "AutoUic";
std::string const genNameRcc = "AutoRcc";

// - Static functions

/// @brief Merges newOpts into baseOpts
/// @arg valueOpts list of options that accept a value
void MergeOptions(std::vector<std::string>& baseOpts,
                  std::vector<std::string> const& newOpts,
                  std::vector<std::string> const& valueOpts, bool isQt5)
{
  typedef std::vector<std::string>::iterator Iter;
  typedef std::vector<std::string>::const_iterator CIter;
  if (newOpts.empty()) {
    return;
  }
  if (baseOpts.empty()) {
    baseOpts = newOpts;
    return;
  }

  std::vector<std::string> extraOpts;
  for (CIter fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd;
       ++fit) {
    std::string const& newOpt = *fit;
    Iter existIt = std::find(baseOpts.begin(), baseOpts.end(), newOpt);
    if (existIt != baseOpts.end()) {
      if (newOpt.size() >= 2) {
        // Acquire the option name
        std::string optName;
        {
          auto oit = newOpt.begin();
          if (*oit == '-') {
            ++oit;
            if (isQt5 && (*oit == '-')) {
              ++oit;
            }
            optName.assign(oit, newOpt.end());
          }
        }
        // Test if this is a value option and change the existing value
        if (!optName.empty() && (std::find(valueOpts.begin(), valueOpts.end(),
                                           optName) != valueOpts.end())) {
          const Iter existItNext(existIt + 1);
          const CIter fitNext(fit + 1);
          if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
            *existItNext = *fitNext;
            ++fit;
          }
        }
      }
    } else {
      extraOpts.push_back(newOpt);
    }
  }
  // Append options
  baseOpts.insert(baseOpts.end(), extraOpts.begin(), extraOpts.end());
}

// - Class definitions

std::string const cmQtAutoGen::ListSep = "<<<S>>>";
unsigned int const cmQtAutoGen::ParallelMax = 64;

std::string const& cmQtAutoGen::GeneratorName(GeneratorT type)
{
  switch (type) {
    case GeneratorT::GEN:
      return genNameGen;
    case GeneratorT::MOC:
      return genNameMoc;
    case GeneratorT::UIC:
      return genNameUic;
    case GeneratorT::RCC:
      return genNameRcc;
  }
  return genNameGen;
}

std::string cmQtAutoGen::GeneratorNameUpper(GeneratorT genType)
{
  return cmSystemTools::UpperCase(cmQtAutoGen::GeneratorName(genType));
}

std::string cmQtAutoGen::Quoted(std::string const& text)
{
  static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a",
                                 "\b", "\\b",  "\f", "\\f",  "\n", "\\n",
                                 "\r", "\\r",  "\t", "\\t",  "\v", "\\v" };

  std::string res = text;
  for (const char* const* it = cm::cbegin(rep); it != cm::cend(rep); it += 2) {
    cmSystemTools::ReplaceString(res, *it, *(it + 1));
  }
  res = '"' + res;
  res += '"';
  return res;
}

std::string cmQtAutoGen::QuotedCommand(std::vector<std::string> const& command)
{
  std::string res;
  for (std::string const& item : command) {
    if (!res.empty()) {
      res.push_back(' ');
    }
    std::string const cesc = cmQtAutoGen::Quoted(item);
    if (item.empty() || (cesc.size() > (item.size() + 2)) ||
        (cesc.find(' ') != std::string::npos)) {
      res += cesc;
    } else {
      res += item;
    }
  }
  return res;
}

std::string cmQtAutoGen::SubDirPrefix(std::string const& filename)
{
  std::string res(cmSystemTools::GetFilenamePath(filename));
  if (!res.empty()) {
    res += '/';
  }
  return res;
}

std::string cmQtAutoGen::AppendFilenameSuffix(std::string const& filename,
                                              std::string const& suffix)
{
  std::string res;
  auto pos = filename.rfind('.');
  if (pos != std::string::npos) {
    const auto it_dot = filename.begin() + pos;
    res.assign(filename.begin(), it_dot);
    res.append(suffix);
    res.append(it_dot, filename.end());
  } else {
    res = filename;
    res.append(suffix);
  }
  return res;
}

void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts,
                                  std::vector<std::string> const& newOpts,
                                  bool isQt5)
{
  static std::vector<std::string> const valueOpts = {
    "tr",      "translate", "postfix", "generator",
    "include", // Since Qt 5.3
    "g"
  };
  MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
}

void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts,
                                  std::vector<std::string> const& newOpts,
                                  bool isQt5)
{
  static std::vector<std::string> const valueOpts = { "name", "root",
                                                      "compress",
                                                      "threshold" };
  MergeOptions(baseOpts, newOpts, valueOpts, isQt5);
}

void cmQtAutoGen::RccListParseContent(std::string const& content,
                                      std::vector<std::string>& files)
{
  cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
  cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");

  const char* contentChars = content.c_str();
  while (fileMatchRegex.find(contentChars)) {
    std::string const qrcEntry = fileMatchRegex.match(1);
    contentChars += qrcEntry.size();
    {
      fileReplaceRegex.find(qrcEntry);
      std::string const tag = fileReplaceRegex.match(1);
      files.push_back(qrcEntry.substr(tag.size()));
    }
  }
}

bool cmQtAutoGen::RccListParseOutput(std::string const& rccStdOut,
                                     std::string const& rccStdErr,
                                     std::vector<std::string>& files,
                                     std::string& error)
{
  // Lambda to strip CR characters
  auto StripCR = [](std::string& line) {
    std::string::size_type cr = line.find('\r');
    if (cr != std::string::npos) {
      line = line.substr(0, cr);
    }
  };

  // Parse rcc std output
  {
    std::istringstream ostr(rccStdOut);
    std::string oline;
    while (std::getline(ostr, oline)) {
      StripCR(oline);
      if (!oline.empty()) {
        files.push_back(oline);
      }
    }
  }
  // Parse rcc error output
  {
    std::istringstream estr(rccStdErr);
    std::string eline;
    while (std::getline(estr, eline)) {
      StripCR(eline);
      if (cmHasLiteralPrefix(eline, "RCC: Error in")) {
        static std::string const searchString = "Cannot find file '";

        std::string::size_type pos = eline.find(searchString);
        if (pos == std::string::npos) {
          error = "rcc lists unparsable output:\n";
          error += cmQtAutoGen::Quoted(eline);
          error += "\n";
          return false;
        }
        pos += searchString.length();
        std::string::size_type sz = eline.size() - pos - 1;
        files.push_back(eline.substr(pos, sz));
      }
    }
  }

  return true;
}

void cmQtAutoGen::RccListConvertFullPath(std::string const& qrcFileDir,
                                         std::vector<std::string>& files)
{
  for (std::string& entry : files) {
    std::string tmp = cmSystemTools::CollapseCombinedPath(qrcFileDir, entry);
    entry = std::move(tmp);
  }
}
