/* 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 "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmSystemTools.h"
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"

#include <algorithm>
#include <array>
#include <sstream>
#include <utility>

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

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

std::string const& cmQtAutoGen::GeneratorName(GenT genType)
{
  static const std::string AutoGen("AutoGen");
  static const std::string AutoMoc("AutoMoc");
  static const std::string AutoUic("AutoUic");
  static const std::string AutoRcc("AutoRcc");

  switch (genType) {
    case GenT::GEN:
      return AutoGen;
    case GenT::MOC:
      return AutoMoc;
    case GenT::UIC:
      return AutoUic;
    case GenT::RCC:
      return AutoRcc;
  }
  return AutoGen;
}

std::string const& cmQtAutoGen::GeneratorNameUpper(GenT genType)
{
  static const std::string AUTOGEN("AUTOGEN");
  static const std::string AUTOMOC("AUTOMOC");
  static const std::string AUTOUIC("AUTOUIC");
  static const std::string AUTORCC("AUTORCC");

  switch (genType) {
    case GenT::GEN:
      return AUTOGEN;
    case GenT::MOC:
      return AUTOMOC;
    case GenT::UIC:
      return AUTOUIC;
    case GenT::RCC:
      return AUTORCC;
  }
  return AUTOGEN;
}

std::string cmQtAutoGen::Tools(bool moc, bool uic, bool rcc)
{
  std::string res;
  std::vector<std::string> lst;
  if (moc) {
    lst.emplace_back("AUTOMOC");
  }
  if (uic) {
    lst.emplace_back("AUTOUIC");
  }
  if (rcc) {
    lst.emplace_back("AUTORCC");
  }
  switch (lst.size()) {
    case 1:
      res += lst.at(0);
      break;
    case 2:
      res += lst.at(0);
      res += " and ";
      res += lst.at(1);
      break;
    case 3:
      res += lst.at(0);
      res += ", ";
      res += lst.at(1);
      res += " and ";
      res += lst.at(2);
      break;
    default:
      break;
  }
  return res;
}

std::string cmQtAutoGen::Quoted(std::string const& text)
{
  const std::array<std::pair<const char*, const char*>, 9> replaces = {
    { { "\\", "\\\\" },
      { "\"", "\\\"" },
      { "\a", "\\a" },
      { "\b", "\\b" },
      { "\f", "\\f" },
      { "\n", "\\n" },
      { "\r", "\\r" },
      { "\t", "\\t" },
      { "\v", "\\v" } }
  };

  std::string res = text;
  for (auto const& pair : replaces) {
    cmSystemTools::ReplaceString(res, pair.first, pair.second);
  }
  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);
}

static void 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()));
    }
  }
}

static bool 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;
}

cmQtAutoGen::RccLister::RccLister() = default;

cmQtAutoGen::RccLister::RccLister(std::string rccExecutable,
                                  std::vector<std::string> listOptions)
  : RccExcutable_(std::move(rccExecutable))
  , ListOptions_(std::move(listOptions))
{
}

bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
                                  std::vector<std::string>& files,
                                  std::string& error, bool verbose) const
{
  error.clear();

  if (!cmSystemTools::FileExists(qrcFile, true)) {
    error = "The resource file ";
    error += Quoted(qrcFile);
    error += " does not exist.";
    return false;
  }

  // Run rcc list command in the directory of the qrc file with the pathless
  // qrc file name argument.  This way rcc prints relative paths.
  // This avoids issues on Windows when the qrc file is in a path that
  // contains non-ASCII characters.
  std::string const fileDir = cmSystemTools::GetFilenamePath(qrcFile);

  if (!this->RccExcutable_.empty() &&
      cmSystemTools::FileExists(this->RccExcutable_, true) &&
      !this->ListOptions_.empty()) {

    bool result = false;
    int retVal = 0;
    std::string rccStdOut;
    std::string rccStdErr;
    {
      std::vector<std::string> cmd;
      cmd.emplace_back(this->RccExcutable_);
      cmd.insert(cmd.end(), this->ListOptions_.begin(),
                 this->ListOptions_.end());
      cmd.emplace_back(cmSystemTools::GetFilenameName(qrcFile));

      // Log command
      if (verbose) {
        std::string msg = "Running command:\n";
        msg += QuotedCommand(cmd);
        msg += '\n';
        cmSystemTools::Stdout(msg);
      }

      result = cmSystemTools::RunSingleCommand(
        cmd, &rccStdOut, &rccStdErr, &retVal, fileDir.c_str(),
        cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
    }
    if (!result || retVal) {
      error = "The rcc list process failed for ";
      error += Quoted(qrcFile);
      error += "\n";
      if (!rccStdOut.empty()) {
        error += rccStdOut;
        error += "\n";
      }
      if (!rccStdErr.empty()) {
        error += rccStdErr;
        error += "\n";
      }
      return false;
    }
    if (!RccListParseOutput(rccStdOut, rccStdErr, files, error)) {
      return false;
    }
  } else {
    // We can't use rcc for the file listing.
    // Read the qrc file content into string and parse it.
    {
      std::string qrcContents;
      {
        cmsys::ifstream ifs(qrcFile.c_str());
        if (ifs) {
          std::ostringstream osst;
          osst << ifs.rdbuf();
          qrcContents = osst.str();
        } else {
          error = "The resource file ";
          error += Quoted(qrcFile);
          error += " is not readable\n";
          return false;
        }
      }
      // Parse string content
      RccListParseContent(qrcContents, files);
    }
  }

  // Convert relative paths to absolute paths
  for (std::string& entry : files) {
    entry = cmSystemTools::CollapseFullPath(entry, fileDir);
  }
  return true;
}
