/* 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 <algorithm>
#include <array>
#include <initializer_list>
#include <sstream>
#include <utility>

#include <cmext/algorithm>

#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"

#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

// - 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::initializer_list<cm::string_view> valueOpts, bool isQt5)
{
  if (newOpts.empty()) {
    return;
  }
  if (baseOpts.empty()) {
    baseOpts = newOpts;
    return;
  }

  std::vector<std::string> extraOpts;
  for (auto fit = newOpts.begin(), fitEnd = newOpts.end(); fit != fitEnd;
       ++fit) {
    std::string const& newOpt = *fit;
    auto 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() && cmContains(valueOpts, optName)) {
          const auto existItNext(existIt + 1);
          const auto fitNext(fit + 1);
          if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
            *existItNext = *fitNext;
            ++fit;
          }
        }
      }
    } else {
      extraOpts.push_back(newOpt);
    }
  }
  // Append options
  cm::append(baseOpts, extraOpts);
}

// - Class definitions

unsigned int const cmQtAutoGen::ParallelMax = 64;

cm::string_view cmQtAutoGen::GeneratorName(GenT genType)
{
  switch (genType) {
    case GenT::GEN:
      return "AutoGen";
    case GenT::MOC:
      return "AutoMoc";
    case GenT::UIC:
      return "AutoUic";
    case GenT::RCC:
      return "AutoRcc";
  }
  return "AutoGen";
}

cm::string_view cmQtAutoGen::GeneratorNameUpper(GenT genType)
{
  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::array<cm::string_view, 3> lst;
  decltype(lst)::size_type num = 0;
  if (moc) {
    lst.at(num++) = "AUTOMOC";
  }
  if (uic) {
    lst.at(num++) = "AUTOUIC";
  }
  if (rcc) {
    lst.at(num++) = "AUTORCC";
  }
  switch (num) {
    case 1:
      return std::string(lst[0]);
    case 2:
      return cmStrCat(lst[0], " and ", lst[1]);
    case 3:
      return cmStrCat(lst[0], ", ", lst[1], " and ", lst[2]);
    default:
      break;
  }
  return std::string();
}

std::string cmQtAutoGen::Quoted(cm::string_view text)
{
  static std::initializer_list<std::pair<const char*, const char*>> const
    replacements = { { "\\", "\\\\" }, { "\"", "\\\"" }, { "\a", "\\a" },
                     { "\b", "\\b" },  { "\f", "\\f" },  { "\n", "\\n" },
                     { "\r", "\\r" },  { "\t", "\\t" },  { "\v", "\\v" } };

  std::string res(text);
  for (auto const& pair : replacements) {
    cmSystemTools::ReplaceString(res, pair.first, pair.second);
  }
  return cmStrCat('"', 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::FileNameWithoutLastExtension(cm::string_view filename)
{
  auto slashPos = filename.rfind('/');
  if (slashPos != cm::string_view::npos) {
    filename.remove_prefix(slashPos + 1);
  }
  auto dotPos = filename.rfind('.');
  return std::string(filename.substr(0, dotPos));
}

std::string cmQtAutoGen::ParentDir(cm::string_view filename)
{
  auto slashPos = filename.rfind('/');
  if (slashPos == cm::string_view::npos) {
    return std::string();
  }
  return std::string(filename.substr(0, slashPos));
}

std::string cmQtAutoGen::SubDirPrefix(cm::string_view filename)
{
  auto slashPos = filename.rfind('/');
  if (slashPos == cm::string_view::npos) {
    return std::string();
  }
  return std::string(filename.substr(0, slashPos + 1));
}

std::string cmQtAutoGen::AppendFilenameSuffix(cm::string_view filename,
                                              cm::string_view suffix)
{
  auto dotPos = filename.rfind('.');
  if (dotPos == cm::string_view::npos) {
    return cmStrCat(filename, suffix);
  }
  return cmStrCat(filename.substr(0, dotPos), suffix,
                  filename.substr(dotPos, filename.size() - dotPos));
}

void cmQtAutoGen::UicMergeOptions(std::vector<std::string>& baseOpts,
                                  std::vector<std::string> const& newOpts,
                                  bool isQt5)
{
  static std::initializer_list<cm::string_view> 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::initializer_list<cm::string_view> 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 = cmStrCat("rcc lists unparsable output:\n",
                           cmQtAutoGen::Quoted(eline), '\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 =
      cmStrCat("The resource file ", Quoted(qrcFile), " 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_);
      cm::append(cmd, this->ListOptions_);
      cmd.emplace_back(cmSystemTools::GetFilenameName(qrcFile));

      // Log command
      if (verbose) {
        cmSystemTools::Stdout(
          cmStrCat("Running command:\n", QuotedCommand(cmd), '\n'));
      }

      result = cmSystemTools::RunSingleCommand(
        cmd, &rccStdOut, &rccStdErr, &retVal, fileDir.c_str(),
        cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
    }
    if (!result || retVal) {
      error =
        cmStrCat("The rcc list process failed for ", Quoted(qrcFile), '\n');
      if (!rccStdOut.empty()) {
        error += cmStrCat(rccStdOut, '\n');
      }
      if (!rccStdErr.empty()) {
        error += cmStrCat(rccStdErr, '\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 = cmStrCat("The resource file ", Quoted(qrcFile),
                           " 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;
}
