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

#include <cstdio>
#include <locale>

#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

#if !defined(CMAKE_BOOTSTRAP)
#  include <cm3p/zlib.h>

#  include "cm_codecvt.hxx"
#endif

cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
{
#ifndef CMAKE_BOOTSTRAP
  if (encoding != codecvt_Encoding::None) {
    this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
  }
#else
  static_cast<void>(encoding);
#endif
}

cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
                                             bool quiet, Encoding encoding)
  : cmGeneratedFileStreamBase(name)
  , Stream(this->TempName.c_str()) // NOLINT(cmake-use-cmsys-fstream)
{
  // Check if the file opened.
  if (!*this && !quiet) {
    cmSystemTools::Error("Cannot open file for write: " + this->TempName);
    cmSystemTools::ReportLastSystemError("");
  }
#ifndef CMAKE_BOOTSTRAP
  if (encoding != codecvt_Encoding::None) {
    this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
  }
#else
  static_cast<void>(encoding);
#endif
  if (encoding == codecvt_Encoding::UTF8_WITH_BOM) {
    // Write the BOM encoding header into the file
    char magic[] = { static_cast<char>(0xEF), static_cast<char>(0xBB),
                     static_cast<char>(0xBF) };
    this->write(magic, 3);
  }
}

cmGeneratedFileStream::~cmGeneratedFileStream()
{
  // This is the first destructor called.  Check the status of the
  // stream and give the information to the private base.  Next the
  // stream will be destroyed which will close the temporary file.
  // Finally the base destructor will be called to replace the
  // destination file.
  this->Okay = !this->fail();
}

cmGeneratedFileStream& cmGeneratedFileStream::Open(std::string const& name,
                                                   bool quiet, bool binaryFlag)
{
  // Store the file name and construct the temporary file name.
  this->cmGeneratedFileStreamBase::Open(name);

  // Open the temporary output file.
  if (binaryFlag) {
    this->Stream::open( // NOLINT(cmake-use-cmsys-fstream)
      this->TempName.c_str(), std::ios::out | std::ios::binary);
  } else {
    this->Stream::open( // NOLINT(cmake-use-cmsys-fstream)
      this->TempName.c_str());
  }

  // Check if the file opened.
  if (!*this && !quiet) {
    cmSystemTools::Error("Cannot open file for write: " + this->TempName);
    cmSystemTools::ReportLastSystemError("");
  }
  return *this;
}

bool cmGeneratedFileStream::Close()
{
  // Save whether the temporary output file is valid before closing.
  this->Okay = !this->fail();

  // Close the temporary output file.
  this->Stream::close(); // NOLINT(cmake-use-cmsys-fstream)

  // Remove the temporary file (possibly by renaming to the real file).
  return this->cmGeneratedFileStreamBase::Close();
}

void cmGeneratedFileStream::SetCopyIfDifferent(bool copy_if_different)
{
  this->CopyIfDifferent = copy_if_different;
}

void cmGeneratedFileStream::SetCompression(bool compression)
{
  this->Compress = compression;
}

void cmGeneratedFileStream::SetCompressionExtraExtension(bool ext)
{
  this->CompressExtraExtension = ext;
}

cmGeneratedFileStreamBase::cmGeneratedFileStreamBase() = default;

cmGeneratedFileStreamBase::cmGeneratedFileStreamBase(std::string const& name)
{
  this->Open(name);
}

cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase()
{
  this->Close();
}

void cmGeneratedFileStreamBase::Open(std::string const& name)
{
  // Save the original name of the file.
  this->Name = cmSystemTools::CollapseFullPath(name);

  // Create the name of the temporary file.
  this->TempName = this->Name;
#if defined(__VMS)
  this->TempName += "_";
#else
  this->TempName += ".";
#endif
  if (!this->TempExt.empty()) {
    this->TempName += this->TempExt;
  } else {
    char buf[64];
    snprintf(buf, sizeof(buf), "tmp%05x",
             cmSystemTools::RandomNumber() & 0xFFFFF);
    this->TempName += buf;
  }

  // Make sure the temporary file that will be used is not present.
  cmSystemTools::RemoveFile(this->TempName);

  std::string dir = cmSystemTools::GetFilenamePath(this->TempName);
  cmSystemTools::MakeDirectory(dir);
}

bool cmGeneratedFileStreamBase::Close()
{
  bool replaced = false;

  std::string resname = this->Name;
  if (this->Compress && this->CompressExtraExtension) {
    resname += ".gz";
  }

  // Only consider replacing the destination file if no error
  // occurred.
  if (!this->Name.empty() && this->Okay &&
      (!this->CopyIfDifferent ||
       cmSystemTools::FilesDiffer(this->TempName, resname))) {
    // The destination is to be replaced.  Rename the temporary to the
    // destination atomically.
    if (this->Compress) {
      std::string gzname = cmStrCat(this->TempName, ".temp.gz");
      if (this->CompressFile(this->TempName, gzname)) {
        this->RenameFile(gzname, resname);
      }
      cmSystemTools::RemoveFile(gzname);
    } else {
      this->RenameFile(this->TempName, resname);
    }

    replaced = true;
  }

  // Else, the destination was not replaced.
  //
  // Always delete the temporary file. We never want it to stay around.
  if (!this->TempName.empty()) {
    cmSystemTools::RemoveFile(this->TempName);
  }

  return replaced;
}

#ifndef CMAKE_BOOTSTRAP
int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
                                            std::string const& newname)
{
  gzFile gf = gzopen(newname.c_str(), "w");
  if (!gf) {
    return 0;
  }
  FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
  if (!ifs) {
    gzclose(gf);
    return 0;
  }
  size_t res;
  size_t const BUFFER_SIZE = 1024;
  char buffer[BUFFER_SIZE];
  while ((res = fread(buffer, 1, BUFFER_SIZE, ifs)) > 0) {
    if (!gzwrite(gf, buffer, static_cast<int>(res))) {
      fclose(ifs);
      gzclose(gf);
      return 0;
    }
  }
  fclose(ifs);
  gzclose(gf);
  return 1;
}
#else
int cmGeneratedFileStreamBase::CompressFile(std::string const&,
                                            std::string const&)
{
  return 0;
}
#endif

int cmGeneratedFileStreamBase::RenameFile(std::string const& oldname,
                                          std::string const& newname)
{
  return cmSystemTools::RenameFile(oldname, newname);
}

void cmGeneratedFileStream::SetName(std::string const& fname)
{
  this->Name = cmSystemTools::CollapseFullPath(fname);
}

void cmGeneratedFileStream::SetTempExt(std::string const& ext)
{
  this->TempExt = ext;
}

void cmGeneratedFileStream::WriteAltEncoding(std::string const& data,
                                             Encoding encoding)
{
#ifndef CMAKE_BOOTSTRAP
  std::locale prevLocale =
    this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
  this->write(data.data(), data.size());
  this->imbue(prevLocale);
#else
  static_cast<void>(encoding);
  this->write(data.data(), data.size());
#endif
}
