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

#include <chrono>
#include <stdexcept>
#include <utility>

#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>

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

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

cmMakefileProfilingData::cmMakefileProfilingData(
  std::string const& profileStream)
{
  std::ios::openmode omode = std::ios::out | std::ios::trunc;
  this->ProfileStream.open(profileStream.c_str(), omode);
  Json::StreamWriterBuilder wbuilder;
  this->JsonWriter =
    std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
  if (!this->ProfileStream.good()) {
    throw std::runtime_error(std::string("Unable to open: ") + profileStream);
  }

  this->ProfileStream << "[";
}

cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
{
  if (this->ProfileStream.good()) {
    try {
      this->ProfileStream << "]";
      this->ProfileStream.close();
    } catch (...) {
      cmSystemTools::Error("Error writing profiling output!");
    }
  }
}

void cmMakefileProfilingData::StartEntry(std::string const& category,
                                         std::string const& name,
                                         cm::optional<Json::Value> args)
{
  /* Do not try again if we previously failed to write to output. */
  if (!this->ProfileStream.good()) {
    return;
  }

  try {
    if (this->ProfileStream.tellp() > 1) {
      this->ProfileStream << ",";
    }
    cmsys::SystemInformation info;
    Json::Value v;
    v["ph"] = "B";
    v["name"] = name;
    v["cat"] = category;
    v["ts"] = static_cast<Json::Value::UInt64>(
      std::chrono::duration_cast<std::chrono::microseconds>(
        std::chrono::steady_clock::now().time_since_epoch())
        .count());
    v["pid"] = static_cast<int>(info.GetProcessId());
    v["tid"] = 0;
    if (args) {
      v["args"] = *std::move(args);
    }

    this->JsonWriter->write(v, &this->ProfileStream);
  } catch (std::ios_base::failure& fail) {
    cmSystemTools::Error(
      cmStrCat("Failed to write to profiling output: ", fail.what()));
  } catch (...) {
    cmSystemTools::Error("Error writing profiling output!");
  }
}

void cmMakefileProfilingData::StopEntry()
{
  /* Do not try again if we previously failed to write to output. */
  if (!this->ProfileStream.good()) {
    return;
  }

  try {
    this->ProfileStream << ",";
    cmsys::SystemInformation info;
    Json::Value v;
    v["ph"] = "E";
    v["ts"] = static_cast<Json::Value::UInt64>(
      std::chrono::duration_cast<std::chrono::microseconds>(
        std::chrono::steady_clock::now().time_since_epoch())
        .count());
    v["pid"] = static_cast<int>(info.GetProcessId());
    v["tid"] = 0;
    this->JsonWriter->write(v, &this->ProfileStream);
  } catch (std::ios_base::failure& fail) {
    cmSystemTools::Error(
      cmStrCat("Failed to write to profiling output:", fail.what()));
  } catch (...) {
    cmSystemTools::Error("Error writing profiling output!");
  }
}

cmMakefileProfilingData::RAII::RAII(cmMakefileProfilingData& data,
                                    std::string const& category,
                                    std::string const& name,
                                    cm::optional<Json::Value> args)
  : Data(&data)
{
  this->Data->StartEntry(category, name, std::move(args));
}

cmMakefileProfilingData::RAII::RAII(RAII&& other) noexcept
  : Data(other.Data)
{
  other.Data = nullptr;
}

cmMakefileProfilingData::RAII::~RAII()
{
  if (this->Data) {
    this->Data->StopEntry();
  }
}

cmMakefileProfilingData::RAII& cmMakefileProfilingData::RAII::operator=(
  RAII&& other) noexcept
{
  if (this->Data) {
    this->Data->StopEntry();
  }
  this->Data = other.Data;
  other.Data = nullptr;
  return *this;
}
