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

#include <algorithm>
#include <string>
#include <vector>

#include <cmext/algorithm>

#include "cmCryptoHash.h"
#include "cmDuration.h"
#include "cmFileLock.h"
#include "cmFileLockResult.h"
#include "cmFileTime.h"
#include "cmProcessOutput.h"
#include "cmQtAutoGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

namespace {

/** \class cmQtAutoRccT
 * \brief AUTORCC generator
 */
class cmQtAutoRccT : public cmQtAutoGenerator
{
public:
  cmQtAutoRccT();
  ~cmQtAutoRccT() override;

  cmQtAutoRccT(cmQtAutoRccT const&) = delete;
  cmQtAutoRccT& operator=(cmQtAutoRccT const&) = delete;

private:
  // -- Utility
  bool IsMultiConfig() const { return this->MultiConfig_; }
  std::string const& GetGenerator() const { return this->Generator_; }
  bool IsXcode() const
  {
    return this->GetGenerator().find("Xcode") != std::string::npos;
  }
  std::string MultiConfigOutput() const;

  // -- Abstract processing interface
  bool InitFromInfo(InfoT const& info) override;
  bool Process() override;
  // -- Settings file
  bool SettingsFileRead();
  bool SettingsFileWrite();
  // -- Tests
  bool TestQrcRccFiles(bool& generate);
  bool TestResources(bool& generate);
  bool TestInfoFile();
  // -- Generation
  bool GenerateRcc();
  bool GenerateWrapper();

  // -- Config settings
  bool MultiConfig_ = false;
  bool CrossConfig_ = false;
  bool UseBetterGraph_ = false;
  std::string Generator_;
  // -- Directories
  std::string AutogenBuildDir_;
  std::string IncludeDir_;
  // -- Qt environment
  std::string RccExecutable_;
  cmFileTime RccExecutableTime_;
  std::vector<std::string> RccListOptions_;
  // -- Job
  std::string LockFile_;
  cmFileLock LockFileLock_;
  std::string QrcFile_;
  std::string QrcFileName_;
  std::string QrcFileDir_;
  cmFileTime QrcFileTime_;
  std::string RccPathChecksum_;
  std::string RccFileName_;
  std::string RccFileOutput_;
  std::string RccFilePublic_;
  cmFileTime RccFileTime_;
  std::string Reason;
  std::vector<std::string> Options_;
  std::vector<std::string> Inputs_;
  // -- Settings file
  std::string SettingsFile_;
  std::string SettingsString_;
  bool SettingsChanged_ = false;
  bool BuildFileChanged_ = false;
};

cmQtAutoRccT::cmQtAutoRccT()
  : cmQtAutoGenerator(GenT::RCC)
{
}
cmQtAutoRccT::~cmQtAutoRccT() = default;

bool cmQtAutoRccT::InitFromInfo(InfoT const& info)
{
  // -- Required settings
  if (!info.GetBool("MULTI_CONFIG", this->MultiConfig_, true) ||
      !info.GetString("GENERATOR", this->Generator_, true) ||
      !info.GetBool("CROSS_CONFIG", this->CrossConfig_, true) ||
      !info.GetBool("USE_BETTER_GRAPH", this->UseBetterGraph_, true) ||
      !info.GetString("BUILD_DIR", this->AutogenBuildDir_, true) ||
      !info.GetStringConfig("INCLUDE_DIR", this->IncludeDir_, true) ||
      !info.GetArrayConfig("RCC_LIST_OPTIONS", this->RccListOptions_, false) ||
      !info.GetString("LOCK_FILE", this->LockFile_, true) ||
      !info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) ||
      !info.GetString("SOURCE", this->QrcFile_, true) ||
      !info.GetString("OUTPUT_CHECKSUM", this->RccPathChecksum_, true) ||
      !info.GetString("OUTPUT_NAME", this->RccFileName_, true) ||
      !info.GetArray("OPTIONS", this->Options_, false)) {
    return false;
  }
  if (this->UseBetterGraph_) {
    if (!info.GetArrayConfig("INPUTS", this->Inputs_, false)) {
      return false;
    }
    if (this->CrossConfig_) {
      std::string const rccExecutableWithConfig =
        "RCC_EXECUTABLE_" + this->ExecutableConfig();
      if (!info.GetString(rccExecutableWithConfig, this->RccExecutable_,
                          true)) {
        return false;
      }
    } else {
      if (!info.GetStringConfig("RCC_EXECUTABLE", this->RccExecutable_,
                                true)) {
        return false;
      }
    }
  } else {
    if (!info.GetString("RCC_EXECUTABLE", this->RccExecutable_, true) ||
        !info.GetArray("RCC_LIST_OPTIONS", this->RccListOptions_, false) ||
        !info.GetArray("INPUTS", this->Inputs_, false)) {
      return false;
    }
  }

  // -- Derive information
  this->QrcFileName_ = cmSystemTools::GetFilenameName(this->QrcFile_);
  this->QrcFileDir_ = cmSystemTools::GetFilenamePath(this->QrcFile_);
  if (IsMultiConfig() && !this->IsXcode() && this->UseBetterGraph_) {
    this->RccFilePublic_ =
      cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, "_",
               this->InfoConfig(), '/', this->RccFileName_);
  } else {
    this->RccFilePublic_ =
      cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, '/',
               this->RccFileName_);
  }

  // rcc output file name
  if (this->IsMultiConfig()) {
    this->RccFileOutput_ =
      cmStrCat(this->IncludeDir_, '/', this->MultiConfigOutput());
  } else {
    this->RccFileOutput_ = this->RccFilePublic_;
  }

  // -- Checks
  if (!this->RccExecutableTime_.Load(this->RccExecutable_)) {
    return info.LogError(cmStrCat("The rcc executable ",
                                  this->MessagePath(this->RccExecutable_),
                                  " does not exist."));
  }

  return true;
}

bool cmQtAutoRccT::Process()
{
  if (!this->SettingsFileRead()) {
    return false;
  }

  // Test if the rcc output needs to be regenerated
  bool generate = false;
  if (!this->TestQrcRccFiles(generate)) {
    return false;
  }
  if (!generate && !this->TestResources(generate)) {
    return false;
  }
  // Generate on demand
  if (generate) {
    if (!this->GenerateRcc()) {
      return false;
    }
  } else {
    // Test if the info file is newer than the output file
    if (!this->TestInfoFile()) {
      return false;
    }
  }

  if (!this->GenerateWrapper()) {
    return false;
  }

  return this->SettingsFileWrite();
}

std::string cmQtAutoRccT::MultiConfigOutput() const
{
  return cmStrCat(this->RccPathChecksum_, '/',
                  AppendFilenameSuffix(this->RccFileName_, "_CMAKE_"));
}

bool cmQtAutoRccT::SettingsFileRead()
{
  // Compose current settings strings
  {
    cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
    auto cha = [&cryptoHash](cm::string_view value) {
      cryptoHash.Append(value);
      cryptoHash.Append(";");
    };
    cha(this->RccExecutable_);
    std::for_each(this->RccListOptions_.begin(), this->RccListOptions_.end(),
                  cha);
    cha(this->QrcFile_);
    cha(this->RccPathChecksum_);
    cha(this->RccFileName_);
    std::for_each(this->Options_.begin(), this->Options_.end(), cha);
    std::for_each(this->Inputs_.begin(), this->Inputs_.end(), cha);
    this->SettingsString_ = cryptoHash.FinalizeHex();
  }

  // Make sure the settings file exists
  if (!cmSystemTools::FileExists(this->SettingsFile_, true)) {
    // Touch the settings file to make sure it exists
    if (!cmSystemTools::Touch(this->SettingsFile_, true)) {
      this->Log().Error(GenT::RCC,
                        cmStrCat("Touching the settings file ",
                                 this->MessagePath(this->SettingsFile_),
                                 " failed."));
      return false;
    }
  }

  // Lock the lock file
  {
    // Make sure the lock file exists
    if (!cmSystemTools::FileExists(this->LockFile_, true)) {
      if (!cmSystemTools::Touch(this->LockFile_, true)) {
        this->Log().Error(GenT::RCC,
                          cmStrCat("Touching the lock file ",
                                   this->MessagePath(this->LockFile_),
                                   " failed."));
        return false;
      }
    }
    // Lock the lock file
    cmFileLockResult lockResult = this->LockFileLock_.Lock(
      this->LockFile_, static_cast<unsigned long>(-1));
    if (!lockResult.IsOk()) {
      this->Log().Error(GenT::RCC,
                        cmStrCat("Locking of the lock file ",
                                 this->MessagePath(this->LockFile_),
                                 " failed.\n", lockResult.GetOutputMessage()));
      return false;
    }
  }

  // Read old settings
  {
    std::string content;
    if (FileRead(content, this->SettingsFile_)) {
      this->SettingsChanged_ =
        (this->SettingsString_ != SettingsFind(content, "rcc"));
      // In case any setting changed clear the old settings file.
      // This triggers a full rebuild on the next run if the current
      // build is aborted before writing the current settings in the end.
      if (this->SettingsChanged_) {
        std::string error;
        if (!FileWrite(this->SettingsFile_, "", &error)) {
          this->Log().Error(GenT::RCC,
                            cmStrCat("Clearing of the settings file ",
                                     this->MessagePath(this->SettingsFile_),
                                     " failed.\n", error));
          return false;
        }
      }
    } else {
      this->SettingsChanged_ = true;
    }
  }

  return true;
}

bool cmQtAutoRccT::SettingsFileWrite()
{
  // Only write if any setting changed
  if (this->SettingsChanged_) {
    if (this->Log().Verbose()) {
      this->Log().Info(GenT::RCC,
                       "Writing settings file " +
                         this->MessagePath(this->SettingsFile_));
    }
    // Write settings file
    std::string content = cmStrCat("rcc:", this->SettingsString_, '\n');
    std::string error;
    if (!FileWrite(this->SettingsFile_, content, &error)) {
      this->Log().Error(GenT::RCC,
                        cmStrCat("Writing of the settings file ",
                                 this->MessagePath(this->SettingsFile_),
                                 " failed.\n", error));
      // Remove old settings file to trigger a full rebuild on the next run
      cmSystemTools::RemoveFile(this->SettingsFile_);
      return false;
    }
  }

  // Unlock the lock file
  this->LockFileLock_.Release();
  return true;
}

/// Do basic checks if rcc generation is required
bool cmQtAutoRccT::TestQrcRccFiles(bool& generate)
{
  // Test if the rcc input file exists
  if (!this->QrcFileTime_.Load(this->QrcFile_)) {
    this->Log().Error(GenT::RCC,
                      cmStrCat("The resources file ",
                               this->MessagePath(this->QrcFile_),
                               " does not exist"));
    return false;
  }

  // Test if the rcc output file exists
  if (!this->RccFileTime_.Load(this->RccFileOutput_)) {
    if (this->Log().Verbose()) {
      this->Reason =
        cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
                 ", because it doesn't exist, from ",
                 this->MessagePath(this->QrcFile_));
    }
    generate = true;
    return true;
  }

  // Test if the settings changed
  if (this->SettingsChanged_) {
    if (this->Log().Verbose()) {
      this->Reason =
        cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
                 ", because the rcc settings changed, from ",
                 this->MessagePath(this->QrcFile_));
    }
    generate = true;
    return true;
  }

  // Test if the rcc output file is older than the .qrc file
  if (this->RccFileTime_.Older(this->QrcFileTime_)) {
    if (this->Log().Verbose()) {
      this->Reason = cmStrCat(
        "Generating ", this->MessagePath(this->RccFileOutput_),
        ", because it is older than ", this->MessagePath(this->QrcFile_),
        ", from ", this->MessagePath(this->QrcFile_));
    }
    generate = true;
    return true;
  }

  // Test if the rcc output file is older than the rcc executable
  if (this->RccFileTime_.Older(this->RccExecutableTime_)) {
    if (this->Log().Verbose()) {
      this->Reason =
        cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
                 ", because it is older than the rcc executable, from ",
                 this->MessagePath(this->QrcFile_));
    }
    generate = true;
    return true;
  }

  return true;
}

bool cmQtAutoRccT::TestResources(bool& generate)
{
  // Read resource files list
  if (this->Inputs_.empty()) {
    std::string error;
    RccLister const lister(this->RccExecutable_, this->RccListOptions_);
    if (!lister.list(this->QrcFile_, this->Inputs_, error,
                     this->Log().Verbose())) {
      this->Log().Error(GenT::RCC,
                        cmStrCat("Listing of ",
                                 this->MessagePath(this->QrcFile_),
                                 " failed.\n", error));
      return false;
    }
  }

  // Check if any resource file is newer than the rcc output file
  for (std::string const& resFile : this->Inputs_) {
    // Check if the resource file exists
    cmFileTime fileTime;
    if (!fileTime.Load(resFile)) {
      this->Log().Error(GenT::RCC,
                        cmStrCat("The resource file ",
                                 this->MessagePath(resFile), " listed in ",
                                 this->MessagePath(this->QrcFile_),
                                 " does not exist."));
      return false;
    }
    // Check if the resource file is newer than the rcc output file
    if (this->RccFileTime_.Older(fileTime)) {
      if (this->Log().Verbose()) {
        this->Reason =
          cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_),
                   ", because it is older than ", this->MessagePath(resFile),
                   ", from ", this->MessagePath(this->QrcFile_));
      }
      generate = true;
      break;
    }
  }
  return true;
}

bool cmQtAutoRccT::TestInfoFile()
{
  // Test if the rcc output file is older than the info file
  if (this->RccFileTime_.Older(this->InfoFileTime())) {
    if (this->Log().Verbose()) {
      this->Log().Info(GenT::RCC,
                       cmStrCat("Touching ",
                                this->MessagePath(this->RccFileOutput_),
                                " because it is older than ",
                                this->MessagePath(this->InfoFile())));
    }
    // Touch build file
    if (!cmSystemTools::Touch(this->RccFileOutput_, false)) {
      this->Log().Error(GenT::RCC,
                        cmStrCat("Touching ",
                                 this->MessagePath(this->RccFileOutput_),
                                 " failed."));
      return false;
    }
    this->BuildFileChanged_ = true;
  }

  return true;
}

bool cmQtAutoRccT::GenerateRcc()
{
  // Make parent directory
  if (!MakeParentDirectory(this->RccFileOutput_)) {
    this->Log().Error(GenT::RCC,
                      cmStrCat("Could not create parent directory of ",
                               this->MessagePath(this->RccFileOutput_)));
    return false;
  }

  // Compose rcc command
  std::vector<std::string> cmd;
  cmd.push_back(this->RccExecutable_);
  cm::append(cmd, this->Options_);
  cmd.emplace_back("-o");
  cmd.push_back(this->RccFileOutput_);
  cmd.push_back(this->QrcFile_);

  // Log reason and command
  if (this->Log().Verbose()) {
    this->Log().Info(GenT::RCC,
                     cmStrCat(this->Reason,
                              cmHasSuffix(this->Reason, '\n') ? "" : "\n",
                              QuotedCommand(cmd), '\n'));
  }

  std::string rccStdOut;
  std::string rccStdErr;
  int retVal = 0;
  bool result = cmSystemTools::RunSingleCommand(
    cmd, &rccStdOut, &rccStdErr, &retVal, this->AutogenBuildDir_.c_str(),
    cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto);
  if (!result || (retVal != 0)) {
    // rcc process failed
    this->Log().ErrorCommand(GenT::RCC,
                             cmStrCat("The rcc process failed to compile\n  ",
                                      this->MessagePath(this->QrcFile_),
                                      "\ninto\n  ",
                                      this->MessagePath(this->RccFileOutput_)),
                             cmd, rccStdOut + rccStdErr);
    cmSystemTools::RemoveFile(this->RccFileOutput_);
    return false;
  }

  // rcc process success
  // Print rcc output
  if (!rccStdOut.empty()) {
    this->Log().Info(GenT::RCC, rccStdOut);
  }
  this->BuildFileChanged_ = true;

  return true;
}

bool cmQtAutoRccT::GenerateWrapper()
{
  // Generate a wrapper source file on demand
  if (this->IsMultiConfig()) {
    // Wrapper file content
    std::string content =
      cmStrCat("// This is an autogenerated configuration wrapper file.\n",
               "// Changes will be overwritten.\n", "#include <",
               this->MultiConfigOutput(), ">\n");

    // Compare with existing file content
    bool fileDiffers = true;
    {
      std::string oldContents;
      if (FileRead(oldContents, this->RccFilePublic_)) {
        fileDiffers = (oldContents != content);
      }
    }
    if (fileDiffers) {
      // Write new wrapper file
      if (this->Log().Verbose()) {
        this->Log().Info(GenT::RCC,
                         cmStrCat("Generating RCC wrapper file ",
                                  this->MessagePath(this->RccFilePublic_)));
      }
      std::string error;
      if (!FileWrite(this->RccFilePublic_, content, &error)) {
        this->Log().Error(GenT::RCC,
                          cmStrCat("Generating RCC wrapper file ",
                                   this->MessagePath(this->RccFilePublic_),
                                   " failed.\n", error));
        return false;
      }
    } else if (this->BuildFileChanged_) {
      // Just touch the wrapper file
      if (this->Log().Verbose()) {
        this->Log().Info(GenT::RCC,
                         cmStrCat("Touching RCC wrapper file ",
                                  this->MessagePath(this->RccFilePublic_)));
      }
      if (!cmSystemTools::Touch(this->RccFilePublic_, false)) {
        this->Log().Error(GenT::RCC,
                          cmStrCat("Touching RCC wrapper file ",
                                   this->MessagePath(this->RccFilePublic_),
                                   " failed."));
        return false;
      }
    }
  }
  return true;
}

} // End of unnamed namespace

bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config,
                 cm::string_view executableConfig)
{
  return cmQtAutoRccT().Run(infoFile, config, executableConfig);
}
