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

#include <chrono>
#include <stdexcept>
#include <vector>

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

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

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

cmMakefileProfilingData::cmMakefileProfilingData(
  const std::string& 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(const cmListFileFunction& lff,
                                         cmListFileContext const& lfc)
{
  /* 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"] = lff.Name.Lower;
    v["cat"] = "cmake";
    v["ts"] = 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;
    Json::Value argsValue;
    if (!lff.Arguments.empty()) {
      std::string args;
      for (const auto& a : lff.Arguments) {
        args += (args.empty() ? "" : " ") + a.Value;
      }
      argsValue["functionArgs"] = args;
    }
    argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
    v["args"] = argsValue;

    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"] = 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!");
  }
}
