/* 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 "cmQtAutoGeneratorRcc.h"

#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmUVHandlePtr.h"

#include <functional>

// -- Class methods

cmQtAutoGeneratorRcc::cmQtAutoGeneratorRcc()
  : MultiConfig_(false)
  , SettingsChanged_(false)
  , Stage_(StageT::SETTINGS_READ)
  , Error_(false)
  , Generate_(false)
  , BuildFileChanged_(false)
{
  // Initialize libuv asynchronous iteration request
  UVRequest().init(*UVLoop(), &cmQtAutoGeneratorRcc::UVPollStage, this);
}

cmQtAutoGeneratorRcc::~cmQtAutoGeneratorRcc()
{
}

bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile)
{
  // -- Utility lambdas
  auto InfoGet = [makefile](std::string const& key) {
    return makefile->GetSafeDefinition(key);
  };
  auto InfoGetList =
    [makefile](std::string const& key) -> std::vector<std::string> {
    std::vector<std::string> list;
    cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
    return list;
  };
  auto InfoGetConfig = [makefile,
                        this](std::string const& key) -> std::string {
    const char* valueConf = nullptr;
    {
      std::string keyConf = key;
      keyConf += '_';
      keyConf += InfoConfig();
      valueConf = makefile->GetDefinition(keyConf);
    }
    if (valueConf == nullptr) {
      valueConf = makefile->GetSafeDefinition(key);
    }
    return std::string(valueConf);
  };
  auto InfoGetConfigList =
    [&InfoGetConfig](std::string const& key) -> std::vector<std::string> {
    std::vector<std::string> list;
    cmSystemTools::ExpandListArgument(InfoGetConfig(key), list);
    return list;
  };

  // -- Read info file
  if (!makefile->ReadListFile(InfoFile().c_str())) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "File processing failed");
    return false;
  }

  // - Configurations
  MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG");

  // - Directories
  AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR");
  if (AutogenBuildDir_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Build directory empty");
    return false;
  }

  IncludeDir_ = InfoGetConfig("ARCC_INCLUDE_DIR");
  if (IncludeDir_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Include directory empty");
    return false;
  }

  // - Rcc executable
  RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
  RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");

  // - Job
  QrcFile_ = InfoGet("ARCC_SOURCE");
  QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_);
  QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_);
  RccPathChecksum_ = InfoGet("ARCC_OUTPUT_CHECKSUM");
  RccFileName_ = InfoGet("ARCC_OUTPUT_NAME");
  Options_ = InfoGetConfigList("ARCC_OPTIONS");
  Inputs_ = InfoGetList("ARCC_INPUTS");

  // - Settings file
  SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE");

  // - Validity checks
  if (SettingsFile_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Settings file name missing");
    return false;
  }
  if (AutogenBuildDir_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(),
                    "Autogen build directory missing");
    return false;
  }
  if (RccExecutable_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "rcc executable missing");
    return false;
  }
  if (QrcFile_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "rcc input file missing");
    return false;
  }
  if (RccFileName_.empty()) {
    Log().ErrorFile(GeneratorT::RCC, InfoFile(), "rcc output file missing");
    return false;
  }

  // Init derived information
  // ------------------------

  RccFilePublic_ = AutogenBuildDir_;
  RccFilePublic_ += '/';
  RccFilePublic_ += RccPathChecksum_;
  RccFilePublic_ += '/';
  RccFilePublic_ += RccFileName_;

  // Compute rcc output file name
  if (IsMultiConfig()) {
    RccFileOutput_ = AutogenBuildDir_;
    RccFileOutput_ += '/';
    RccFileOutput_ += IncludeDir_;
    RccFileOutput_ += '/';
    RccFileOutput_ += MultiConfigOutput();
  } else {
    RccFileOutput_ = RccFilePublic_;
  }

  return true;
}

bool cmQtAutoGeneratorRcc::Process()
{
  // Run libuv event loop
  UVRequest().send();
  if (uv_run(UVLoop(), UV_RUN_DEFAULT) == 0) {
    if (Error_) {
      return false;
    }
  } else {
    return false;
  }
  return true;
}

void cmQtAutoGeneratorRcc::UVPollStage(uv_async_t* handle)
{
  reinterpret_cast<cmQtAutoGeneratorRcc*>(handle->data)->PollStage();
}

void cmQtAutoGeneratorRcc::PollStage()
{
  switch (Stage_) {
    // -- Initialize
    case StageT::SETTINGS_READ:
      SettingsFileRead();
      SetStage(StageT::TEST_QRC_RCC_FILES);
      break;

    // -- Change detection
    case StageT::TEST_QRC_RCC_FILES:
      if (TestQrcRccFiles()) {
        SetStage(StageT::GENERATE);
      } else {
        SetStage(StageT::TEST_RESOURCES_READ);
      }
      break;
    case StageT::TEST_RESOURCES_READ:
      if (TestResourcesRead()) {
        SetStage(StageT::TEST_RESOURCES);
      }
      break;
    case StageT::TEST_RESOURCES:
      if (TestResources()) {
        SetStage(StageT::GENERATE);
      } else {
        SetStage(StageT::TEST_INFO_FILE);
      }
      break;
    case StageT::TEST_INFO_FILE:
      TestInfoFile();
      SetStage(StageT::GENERATE_WRAPPER);
      break;

    // -- Generation
    case StageT::GENERATE:
      GenerateParentDir();
      SetStage(StageT::GENERATE_RCC);
      break;
    case StageT::GENERATE_RCC:
      if (GenerateRcc()) {
        SetStage(StageT::GENERATE_WRAPPER);
      }
      break;
    case StageT::GENERATE_WRAPPER:
      GenerateWrapper();
      SetStage(StageT::SETTINGS_WRITE);
      break;

    // -- Finalize
    case StageT::SETTINGS_WRITE:
      SettingsFileWrite();
      SetStage(StageT::FINISH);
      break;
    case StageT::FINISH:
      // Clear all libuv handles
      UVRequest().reset();
      // Set highest END stage manually
      Stage_ = StageT::END;
      break;
    case StageT::END:
      break;
  }
}

void cmQtAutoGeneratorRcc::SetStage(StageT stage)
{
  if (Error_) {
    stage = StageT::FINISH;
  }
  // Only allow to increase the stage
  if (Stage_ < stage) {
    Stage_ = stage;
    UVRequest().send();
  }
}

std::string cmQtAutoGeneratorRcc::MultiConfigOutput() const
{
  static std::string const suffix = "_CMAKE_";
  std::string res;
  res += RccPathChecksum_;
  res += '/';
  res += AppendFilenameSuffix(RccFileName_, suffix);
  return res;
}

void cmQtAutoGeneratorRcc::SettingsFileRead()
{
  // Compose current settings strings
  {
    cmCryptoHash crypt(cmCryptoHash::AlgoSHA256);
    std::string const sep(" ~~~ ");
    {
      std::string str;
      str += RccExecutable_;
      str += sep;
      str += cmJoin(RccListOptions_, ";");
      str += sep;
      str += QrcFile_;
      str += sep;
      str += RccPathChecksum_;
      str += sep;
      str += RccFileName_;
      str += sep;
      str += cmJoin(Options_, ";");
      str += sep;
      str += cmJoin(Inputs_, ";");
      str += sep;
      SettingsString_ = crypt.HashString(str);
    }
  }

  // Read old settings
  {
    std::string content;
    if (FileSys().FileRead(content, SettingsFile_)) {
      SettingsChanged_ = (SettingsString_ != SettingsFind(content, "rcc"));
      // In case any setting changed remove 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 (SettingsChanged_) {
        FileSys().FileRemove(SettingsFile_);
      }
    } else {
      SettingsChanged_ = true;
    }
  }
}

void cmQtAutoGeneratorRcc::SettingsFileWrite()
{
  // Only write if any setting changed
  if (SettingsChanged_) {
    if (Log().Verbose()) {
      Log().Info(GeneratorT::RCC,
                 "Writing settings file " + Quoted(SettingsFile_));
    }
    // Write settings file
    std::string content = "rcc:";
    content += SettingsString_;
    content += '\n';
    if (!FileSys().FileWrite(GeneratorT::RCC, SettingsFile_, content)) {
      Log().ErrorFile(GeneratorT::RCC, SettingsFile_,
                      "Settings file writing failed");
      // Remove old settings file to trigger a full rebuild on the next run
      FileSys().FileRemove(SettingsFile_);
      Error_ = true;
    }
  }
}

bool cmQtAutoGeneratorRcc::TestQrcRccFiles()
{
  // Do basic checks if rcc generation is required

  // Test if the rcc output file exists
  if (!FileSys().FileExists(RccFileOutput_)) {
    if (Log().Verbose()) {
      std::string reason = "Generating ";
      reason += Quoted(RccFileOutput_);
      reason += " from its source file ";
      reason += Quoted(QrcFile_);
      reason += " because it doesn't exist";
      Log().Info(GeneratorT::RCC, reason);
    }
    Generate_ = true;
    return Generate_;
  }

  // Test if the settings changed
  if (SettingsChanged_) {
    if (Log().Verbose()) {
      std::string reason = "Generating ";
      reason += Quoted(RccFileOutput_);
      reason += " from ";
      reason += Quoted(QrcFile_);
      reason += " because the RCC settings changed";
      Log().Info(GeneratorT::RCC, reason);
    }
    Generate_ = true;
    return Generate_;
  }

  // Test if the rcc output file is older than the .qrc file
  {
    bool isOlder = false;
    {
      std::string error;
      isOlder = FileSys().FileIsOlderThan(RccFileOutput_, QrcFile_, &error);
      if (!error.empty()) {
        Log().ErrorFile(GeneratorT::RCC, QrcFile_, error);
        Error_ = true;
      }
    }
    if (isOlder) {
      if (Log().Verbose()) {
        std::string reason = "Generating ";
        reason += Quoted(RccFileOutput_);
        reason += " because it is older than ";
        reason += Quoted(QrcFile_);
        Log().Info(GeneratorT::RCC, reason);
      }
      Generate_ = true;
    }
  }

  return Generate_;
}

bool cmQtAutoGeneratorRcc::TestResourcesRead()
{
  if (!Inputs_.empty()) {
    // Inputs are known already
    return true;
  }

  if (!RccListOptions_.empty()) {
    // Start a rcc list process and parse the output
    if (Process_) {
      // Process is running already
      if (Process_->IsFinished()) {
        // Process is finished
        if (!ProcessResult_.error()) {
          // Process success
          std::string parseError;
          if (!RccListParseOutput(ProcessResult_.StdOut, ProcessResult_.StdErr,
                                  Inputs_, parseError)) {
            Log().ErrorFile(GeneratorT::RCC, QrcFile_, parseError);
            Error_ = true;
          }
        } else {
          Log().ErrorFile(GeneratorT::RCC, QrcFile_,
                          ProcessResult_.ErrorMessage);
          Error_ = true;
        }
        // Clean up
        Process_.reset();
        ProcessResult_.reset();
      } else {
        // Process is not finished, yet.
        return false;
      }
    } else {
      // Start a new process
      // rcc prints relative entry paths when started in the directory of the
      // qrc file with a pathless qrc file name argument.
      // This is important because on Windows absolute paths returned by rcc
      // might contain bad multibyte characters when the qrc file path
      // contains non-ASCII pcharacters.
      std::vector<std::string> cmd;
      cmd.push_back(RccExecutable_);
      cmd.insert(cmd.end(), RccListOptions_.begin(), RccListOptions_.end());
      cmd.push_back(QrcFileName_);
      // We're done here if the process fails to start
      return !StartProcess(QrcFileDir_, cmd, false);
    }
  } else {
    // rcc does not support the --list command.
    // Read the qrc file content and parse it.
    std::string qrcContent;
    if (FileSys().FileRead(GeneratorT::RCC, qrcContent, QrcFile_)) {
      RccListParseContent(qrcContent, Inputs_);
    }
  }

  if (!Inputs_.empty()) {
    // Convert relative paths to absolute paths
    RccListConvertFullPath(QrcFileDir_, Inputs_);
  }

  return true;
}

bool cmQtAutoGeneratorRcc::TestResources()
{
  if (Inputs_.empty()) {
    return true;
  }
  {
    std::string error;
    for (std::string const& resFile : Inputs_) {
      // Check if the resource file exists
      if (!FileSys().FileExists(resFile)) {
        error = "Could not find the resource file\n  ";
        error += Quoted(resFile);
        error += '\n';
        Log().ErrorFile(GeneratorT::RCC, QrcFile_, error);
        Error_ = true;
        break;
      }
      // Check if the resource file is newer than the build file
      if (FileSys().FileIsOlderThan(RccFileOutput_, resFile, &error)) {
        if (Log().Verbose()) {
          std::string reason = "Generating ";
          reason += Quoted(RccFileOutput_);
          reason += " from ";
          reason += Quoted(QrcFile_);
          reason += " because it is older than ";
          reason += Quoted(resFile);
          Log().Info(GeneratorT::RCC, reason);
        }
        Generate_ = true;
        break;
      }
      // Print error and break on demand
      if (!error.empty()) {
        Log().ErrorFile(GeneratorT::RCC, QrcFile_, error);
        Error_ = true;
        break;
      }
    }
  }

  return Generate_;
}

void cmQtAutoGeneratorRcc::TestInfoFile()
{
  // Test if the rcc output file is older than the info file
  {
    bool isOlder = false;
    {
      std::string error;
      isOlder = FileSys().FileIsOlderThan(RccFileOutput_, InfoFile(), &error);
      if (!error.empty()) {
        Log().ErrorFile(GeneratorT::RCC, QrcFile_, error);
        Error_ = true;
      }
    }
    if (isOlder) {
      if (Log().Verbose()) {
        std::string reason = "Touching ";
        reason += Quoted(RccFileOutput_);
        reason += " because it is older than ";
        reason += Quoted(InfoFile());
        Log().Info(GeneratorT::RCC, reason);
      }
      // Touch build file
      FileSys().Touch(RccFileOutput_);
      BuildFileChanged_ = true;
    }
  }
}

void cmQtAutoGeneratorRcc::GenerateParentDir()
{
  // Make sure the parent directory exists
  if (!FileSys().MakeParentDirectory(GeneratorT::RCC, RccFileOutput_)) {
    Error_ = true;
  }
}

/**
 * @return True when finished
 */
bool cmQtAutoGeneratorRcc::GenerateRcc()
{
  if (!Generate_) {
    // Nothing to do
    return true;
  }

  if (Process_) {
    // Process is running already
    if (Process_->IsFinished()) {
      // Process is finished
      if (!ProcessResult_.error()) {
        // Rcc process success
        // Print rcc output
        if (!ProcessResult_.StdOut.empty()) {
          Log().Info(GeneratorT::RCC, ProcessResult_.StdOut);
        }
        BuildFileChanged_ = true;
      } else {
        // Rcc process failed
        {
          std::string emsg = "The rcc process failed to compile\n  ";
          emsg += Quoted(QrcFile_);
          emsg += "\ninto\n  ";
          emsg += Quoted(RccFileOutput_);
          if (ProcessResult_.error()) {
            emsg += "\n";
            emsg += ProcessResult_.ErrorMessage;
          }
          Log().ErrorCommand(GeneratorT::RCC, emsg, Process_->Setup().Command,
                             ProcessResult_.StdOut);
        }
        FileSys().FileRemove(RccFileOutput_);
        Error_ = true;
      }
      // Clean up
      Process_.reset();
      ProcessResult_.reset();
    } else {
      // Process is not finished, yet.
      return false;
    }
  } else {
    // Start a rcc process
    std::vector<std::string> cmd;
    cmd.push_back(RccExecutable_);
    cmd.insert(cmd.end(), Options_.begin(), Options_.end());
    cmd.push_back("-o");
    cmd.push_back(RccFileOutput_);
    cmd.push_back(QrcFile_);
    // We're done here if the process fails to start
    return !StartProcess(AutogenBuildDir_, cmd, true);
  }

  return true;
}

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

    // Write content to file
    if (FileSys().FileDiffers(RccFilePublic_, content)) {
      // Write new wrapper file
      if (Log().Verbose()) {
        Log().Info(GeneratorT::RCC,
                   "Generating RCC wrapper file " + RccFilePublic_);
      }
      if (!FileSys().FileWrite(GeneratorT::RCC, RccFilePublic_, content)) {
        Log().ErrorFile(GeneratorT::RCC, RccFilePublic_,
                        "RCC wrapper file writing failed");
        Error_ = true;
      }
    } else if (BuildFileChanged_) {
      // Just touch the wrapper file
      if (Log().Verbose()) {
        Log().Info(GeneratorT::RCC,
                   "Touching RCC wrapper file " + RccFilePublic_);
      }
      FileSys().Touch(RccFilePublic_);
    }
  }
}

bool cmQtAutoGeneratorRcc::StartProcess(
  std::string const& workingDirectory, std::vector<std::string> const& command,
  bool mergedOutput)
{
  // Log command
  if (Log().Verbose()) {
    std::string msg = "Running command:\n";
    msg += QuotedCommand(command);
    msg += '\n';
    Log().Info(GeneratorT::RCC, msg);
  }

  // Create process handler
  Process_ = cm::make_unique<ReadOnlyProcessT>();
  Process_->setup(&ProcessResult_, mergedOutput, command, workingDirectory);
  // Start process
  if (!Process_->start(UVLoop(),
                       std::bind(&cm::uv_async_ptr::send, &UVRequest()))) {
    Log().ErrorFile(GeneratorT::RCC, QrcFile_, ProcessResult_.ErrorMessage);
    Error_ = true;
    // Clean up
    Process_.reset();
    ProcessResult_.reset();
    return false;
  }
  return true;
}
