//===-- Application to analyze benchmark JSON files -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "automemcpy/ResultAnalyzer.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/MemoryBuffer.h"

namespace llvm {

// User can specify one or more json filenames to process on the command line.
static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,
                                            cl::desc("<input json files>"));

namespace automemcpy {

// This is defined in the autogenerated 'Implementations.cpp' file.
extern ArrayRef<NamedFunctionDescriptor> getFunctionDescriptors();

// Iterates over all functions and fills a map of function name to function
// descriptor pointers.
static StringMap<const FunctionDescriptor *> createFunctionDescriptorMap() {
  StringMap<const FunctionDescriptor *> Descriptors;
  for (const NamedFunctionDescriptor &FD : getFunctionDescriptors())
    Descriptors.insert_or_assign(FD.Name, &FD.Desc);
  return Descriptors;
}

// Retrieves the function descriptor for a particular function name.
static const FunctionDescriptor &getFunctionDescriptor(StringRef FunctionName) {
  static StringMap<const FunctionDescriptor *> Descriptors =
      createFunctionDescriptorMap();
  const auto *FD = Descriptors.lookup(FunctionName);
  if (!FD)
    report_fatal_error(
        Twine("No FunctionDescriptor for ").concat(FunctionName));
  return *FD;
}

// Functions and distributions names are stored quite a few times so it's more
// efficient to internalize these strings and refer to them through 'StringRef'.
static StringRef getInternalizedString(StringRef VolatileStr) {
  static llvm::StringSet<> StringCache;
  return StringCache.insert(VolatileStr).first->getKey();
}

// Helper function for the LLVM JSON API.
bool fromJSON(const json::Value &V, Sample &Out, json::Path P) {
  std::string Label;
  json::ObjectMapper O(V, P);
  if (O && O.map("bytes_per_second", Out.BytesPerSecond) &&
      O.map("label", Label)) {
    const auto LabelPair = StringRef(Label).split(',');
    Out.Id.Function.Name = getInternalizedString(LabelPair.first);
    Out.Id.Function.Type = getFunctionDescriptor(LabelPair.first).Type;
    Out.Id.Distribution.Name = getInternalizedString(LabelPair.second);
    return true;
  }
  return false;
}

// An object to represent the content of the JSON file.
// This is easier to parse/serialize JSON when the structures of the json file
// maps the structure of the object.
struct JsonFile {
  std::vector<Sample> Samples;
};

// Helper function for the LLVM JSON API.
bool fromJSON(const json::Value &V, JsonFile &JF, json::Path P) {
  json::ObjectMapper O(V, P);
  return O && O.map("benchmarks", JF.Samples);
}

// Global object to ease error reporting, it consumes errors and crash the
// application with a meaningful message.
static ExitOnError ExitOnErr;

// Main JSON parsing method. Reads the content of the file pointed to by
// 'Filename' and returns a JsonFile object.
JsonFile parseJsonResultFile(StringRef Filename) {
  auto Buf = ExitOnErr(errorOrToExpected(
      MemoryBuffer::getFile(Filename, /*bool IsText=*/true,
                            /*RequiresNullTerminator=*/false)));
  auto JsonValue = ExitOnErr(json::parse(Buf->getBuffer()));
  json::Path::Root Root;
  JsonFile JF;
  if (!fromJSON(JsonValue, JF, Root))
    ExitOnErr(Root.getError());
  return JF;
}

// Serializes the 'GradeHisto' to the provided 'Stream'.
static void Serialize(raw_ostream &Stream, const GradeHistogram &GH) {
  static constexpr std::array<StringRef, 9> kCharacters = {
      " ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"};

  const size_t Max = *std::max_element(GH.begin(), GH.end());
  for (size_t I = 0; I < GH.size(); ++I) {
    size_t Index = (float(GH[I]) / Max) * (kCharacters.size() - 1);
    Stream << kCharacters.at(Index);
  }
}

int Main(int argc, char **argv) {
  ExitOnErr.setBanner("Automemcpy Json Results Analyzer stopped with error: ");
  cl::ParseCommandLineOptions(argc, argv, "Automemcpy Json Results Analyzer\n");

  // Reads all samples stored in the input JSON files.
  std::vector<Sample> Samples;
  for (const auto &Filename : InputFilenames) {
    auto Result = parseJsonResultFile(Filename);
    llvm::append_range(Samples, Result.Samples);
  }

  // Extracts median of throughputs.
  std::vector<FunctionData> Functions = getThroughputs(Samples);
  fillScores(Functions);
  castVotes(Functions);

  // TODO: Implement tie breaking algorithm.
  std::sort(Functions.begin(), Functions.end(),
            [](const FunctionData &A, const FunctionData &B) {
              return A.FinalGrade < B.FinalGrade;
            });

  // Present data by function type.
  std::stable_sort(Functions.begin(), Functions.end(),
                   [](const FunctionData &A, const FunctionData &B) {
                     return A.Id.Type < B.Id.Type;
                   });

  // Print result.
  for (const FunctionData &Function : Functions) {
    outs() << formatv("{0,-10}", Grade::getString(Function.FinalGrade));
    outs() << " |";
    Serialize(outs(), Function.GradeHisto);
    outs() << "| ";
    outs().resetColor();
    outs() << formatv("{0,+25}", Function.Id.Name);
    outs() << "\n";
  }

  return EXIT_SUCCESS;
}

} // namespace automemcpy
} // namespace llvm

int main(int argc, char **argv) { return llvm::automemcpy::Main(argc, argv); }
