//===- DTLTODistributionDriver.cpp - DTLTO Distribution Driver ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// \file
// This file implements the Integrated Distributed ThinLTO driver that prepares
// the compilation job descriptions and invokes the external distributor.
//
//===----------------------------------------------------------------------===//

#include "llvm/DTLTO/DTLTO.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"

#include <string>

using namespace llvm;

// Generates a JSON file describing the backend compilations, for the
// distributor.
Error lto::DistributionDriver::emitJson() {
  using json::Array;
  std::error_code EC;
  raw_fd_ostream OS(DistributorJsonFile, EC);
  if (EC)
    return createStringError(EC, "Error while creating Json file");

  json::OStream JOS(OS);
  JOS.object([&]() {
    // Information common to all jobs.
    JOS.attributeObject("common", [&]() {
      JOS.attribute("linker_output", Params.LinkerOutputFile);

      JOS.attributeArray("args", [&]() {
        JOS.value(Params.RemoteCompiler);

        // Forward any supplied prepend options.
        if (!Params.RemoteCompilerPrependArgs.empty())
          for (auto &A : Params.RemoteCompilerPrependArgs)
            JOS.value(A);

        JOS.value("-c");

        JOS.value(std::string("--target=") + Params.TargetTriple.str());

        for (const auto &A : Params.CodegenOptions)
          JOS.value(A);
      });

      JOS.attribute("inputs", Array(Params.CommonInputs));
    });

    // Per-compilation-job information.
    JOS.attributeArray("jobs", [&]() {
      for (const auto &J : Jobs) {
        assert(J.Task != 0);
        if (J.Cached) {
          continue;
        }

        SmallVector<StringRef, 2> Inputs;
        SmallVector<StringRef, 1> Outputs;

        JOS.object([&]() {
          JOS.attributeArray("args", [&]() {
            JOS.value(J.ModuleID);
            Inputs.push_back(J.ModuleID);

            JOS.value(
                std::string("-fthinlto-index=" + J.SummaryIndexPath.str()));
            Inputs.push_back(J.SummaryIndexPath);

            JOS.value("-o");
            JOS.value(J.NativeObjectPath);
            Outputs.push_back(J.NativeObjectPath);
          });

          // Add the bitcode files from which imports will be made. These do
          // not explicitly appear on the backend compilation command lines
          // but are recorded in the summary index shards.
          append_range(Inputs, J.ImportsFilesList);
          JOS.attribute("inputs", Array(Inputs));

          JOS.attribute("outputs", Array(Outputs));
        });
      }
    });
  });

  return Error::success();
}

// Saves JSON file on a filesystem.
Error lto::DistributionDriver::saveJson() {
  DistributorJsonFile = sys::path::parent_path(Params.LinkerOutputFile);
  TimeTraceScope TimeScope("Emit DTLTO JSON");
  sys::path::append(DistributorJsonFile,
                    sys::path::stem(Params.LinkerOutputFile) + "." +
                        itostr(sys::Process::getProcessId()) +
                        ".dist-file.json");
  if (Error E = emitJson())
    return make_error<StringError>(
        BCError + "failed to generate distributor JSON script: " +
            DistributorJsonFile,
        errorToErrorCode(std::move(E)));

  // Add JSON file to the cleanup files list.
  if (!SaveTemps)
    AddToCleanup(DistributorJsonFile);
  return Error::success();
}

// Invokes the distributor to compile uncached ThinLTO modules remotely.
Error lto::DistributionDriver::operator()() {
  if (Error E = saveJson())
    return E;

  TimeTraceScope TimeScope("Execute DTLTO distributor", Params.DistributorPath);
  SmallVector<StringRef, 3> Args = {Params.DistributorPath};
  append_range(Args, Params.DistributorArgs);
  Args.push_back(DistributorJsonFile);
  std::string ErrMsg;
  if (sys::ExecuteAndWait(Args[0], Args,
                          /*Env=*/std::nullopt, /*Redirects=*/{},
                          /*SecondsToWait=*/0, /*MemoryLimit=*/0, &ErrMsg)) {
    return make_error<StringError>(
        BCError + "distributor execution failed" +
            (!ErrMsg.empty() ? ": " + ErrMsg + Twine(".") : Twine(".")),
        inconvertibleErrorCode());
  }
  return Error::success();
}
