// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "rs_bindings_from_cc/cmdline.h"

#include <algorithm>
#include <fstream>
#include <iterator>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "absl/debugging/leak_check.h"
#include "absl/flags/flag.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "common/ffi_types.h"
#include "common/status_macros.h"
#include "rs_bindings_from_cc/bazel_types.h"
#include "rs_bindings_from_cc/cmdline_flags.h"
#include "rs_bindings_from_cc/ir.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/JSON.h"

ABSL_FLAG(bool, do_nothing, false,
          "if set to true the tool will produce empty files "
          "(useful for testing Bazel integration)");
ABSL_FLAG(std::string, rs_out, "",
          "output path for the Rust source file with bindings");
ABSL_FLAG(std::string, cc_out, "",
          "output path for the C++ source file with bindings implementation");
ABSL_FLAG(std::string, ir_out, "",
          "(optional) output path for the JSON IR. If not present, the JSON IR "
          "will not be dumped.");
ABSL_FLAG(std::string, crubit_support_path_format, "",
          "the format of `#include` for including Crubit C++ support library "
          "headers in the "
          "generated .cc files, in the format specifier, use `{header}` as the "
          "placeholder. For "
          "example, to include `support_header.h` as "
          "`#include <crubit/support/support_header.h>, specify "
          "`<crubit/support/{header}>`; for "
          "`#include \"crubit/support/support_header.h\", specify "
          "`\"crubit/support/{header}`,");
ABSL_FLAG(std::string, clang_format_exe_path, "",
          "Path to a clang-format executable that will be used to format the "
          ".cc files generated by the tool.");
ABSL_FLAG(std::string, rustfmt_exe_path, "",
          "Path to a rustfmt executable that will be used to format the "
          ".rs files generated by the tool.");
ABSL_FLAG(std::string, rustfmt_config_path, "",
          "(optional) path to a rustfmt.toml file that should replace the "
          "default formatting of the .rs files generated by the tool.");
ABSL_FLAG(std::vector<std::string>, public_headers, std::vector<std::string>(),
          "public headers of the cc_library this tool should generate bindings "
          "for, in a format suitable for usage in google3-relative quote "
          "include (#include \"\"). Note that these can be a subset of headers "
          "attributed to the target via target_args. For example, "
          "unparseable headers may be removed frp, public_headers, but kept "
          "attributed to that target in target_args.");
ABSL_FLAG(std::string, target, "", "The target to generate bindings for.");
ABSL_FLAG(std::string, target_args, "",
          "Per-target Crubit arguments, encoded as a JSON array. This contains "
          "both the list of headers assigned to the target (h), and the set of "
          "enabled features (f). For example:"
          "[\n"
          "  {\n"
          "     \"t\": \"//foo/bar:baz\",\n"
          "     \"h\": [\"foo/bar/header1.h\", \"foo/bar/header2.h\"],\n"
          "     \"f\": [\"supported\"]\n"
          "  },\n"
          "...\n"
          "]");
ABSL_FLAG(std::vector<std::string>, extra_rs_srcs, std::vector<std::string>(),
          "Additional Rust source files to include into the crate.");
ABSL_FLAG(std::vector<std::string>, srcs_to_scan_for_instantiations,
          std::vector<std::string>(),
          "[template instantiation mode only] all Rust source files of a crate "
          "for which we are instantiating templates.");
ABSL_FLAG(std::string, instantiations_out, "",
          "[template instantiation mode only] output path for the JSON file "
          "with mapping from a template instantiation to a generated Rust "
          "struct name. This file is used by cc_template! macro expansion.");
ABSL_FLAG(std::string, namespaces_out, "",
          "(optional) output path for the JSON file containing the target's"
          "namespace hierarchy.");
ABSL_FLAG(std::string, error_report_out, "",
          "(optional) output path for the JSON error report");
ABSL_FLAG(bool, generate_source_location_in_doc_comment, true,
          "add the source code location from which the binding originates in"
          "the doc comment of the binding");

namespace crubit {

namespace {

struct TargetArgs {
  std::string target;
  std::vector<std::string> headers;
  std::vector<std::string> features;
};

bool fromJSON(const llvm::json::Value& json, TargetArgs& out,
              llvm::json::Path path) {
  llvm::json::ObjectMapper mapper(json, path);
  return mapper && mapper.map("t", out.target) &&
         mapper.mapOptional("h", out.headers) &&
         mapper.mapOptional("f", out.features);
}

std::vector<HeaderName> PublicHeaders() {
  std::vector<HeaderName> public_headers;
  const std::vector<std::string>& public_headers_string =
      absl::GetFlag(FLAGS_public_headers);
  std::transform(public_headers_string.begin(), public_headers_string.end(),
                 std::back_inserter(public_headers),
                 [](const std::string& s) { return HeaderName(s); });
  return public_headers;
}
}  // namespace

namespace internal {
absl::Status ParseTargetArgs(absl::string_view target_args_str,
                             CmdlineArgs& args) {
  if (target_args_str.empty()) {
    return absl::InvalidArgumentError("please specify --target_args");
  }
  auto target_args =
      llvm::json::parse<std::vector<TargetArgs>>(std::move(target_args_str));
  if (auto err = target_args.takeError()) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Malformed `--target_args` argument: ", toString(std::move(err))));
  }
  for (const TargetArgs& it : *target_args) {
    const std::string& target = it.target;
    if (target.empty()) {
      return absl::InvalidArgumentError(
          "Expected `t` fields of `--target_args` to be a non-empty "
          "string");
    }
    for (const std::string& header : it.headers) {
      if (header.empty()) {
        return absl::InvalidArgumentError(
            "Expected `h` (header) fields of `--target_args` to be an "
            "array of non-empty strings");
      }
      BazelLabel target_label(target);
      auto [it, inserted] = args.headers_to_targets.try_emplace(
          HeaderName(header), std::move(target_label));
      if (!inserted) {
        LOG(WARNING) << "The `--target_args` cmdline argument assigns `"
                     << header << "` header to two conflicting targets: `"
                     << target << "` vs `" << it->second.value() << "`";
        // Assign the one that comes first alphabetically, to get a consistent
        // result.
        if (target_label.value() < it->second.value()) {
          it->second = std::move(target_label);
        }
      }
    }
    for (const std::string& feature : it.features) {
      if (feature.empty()) {
        return absl::InvalidArgumentError(
            "Expected `f` (feature) fields of `--target_args` to be an "
            "array of non-empty strings");
      }
      args.target_to_features[BazelLabel(target)].insert(feature);
    }
  }
  return absl::OkStatus();
}

}  // namespace internal

absl::StatusOr<Cmdline> Cmdline::FromFlags() {
  auto args = CmdlineArgs{
      .current_target = BazelLabel(absl::GetFlag(FLAGS_target)),
      .cc_out = absl::GetFlag(FLAGS_cc_out),
      .rs_out = absl::GetFlag(FLAGS_rs_out),
      .ir_out = absl::GetFlag(FLAGS_ir_out),
      .namespaces_out = absl::GetFlag(FLAGS_namespaces_out),
      .crubit_support_path_format =
          absl::GetFlag(FLAGS_crubit_support_path_format),
      .clang_format_exe_path = absl::GetFlag(FLAGS_clang_format_exe_path),
      .rustfmt_exe_path = absl::GetFlag(FLAGS_rustfmt_exe_path),
      .rustfmt_config_path = absl::GetFlag(FLAGS_rustfmt_config_path),
      .error_report_out = absl::GetFlag(FLAGS_error_report_out),
      .do_nothing = absl::GetFlag(FLAGS_do_nothing),
      .generate_source_location_in_doc_comment =
          absl::GetFlag(FLAGS_generate_source_location_in_doc_comment)
              ? SourceLocationDocComment::Enabled
              : SourceLocationDocComment::Disabled,
      .public_headers = PublicHeaders(),
      .extra_rs_srcs = absl::GetFlag(FLAGS_extra_rs_srcs),
      .srcs_to_scan_for_instantiations =
          absl::GetFlag(FLAGS_srcs_to_scan_for_instantiations),
      .instantiations_out = absl::GetFlag(FLAGS_instantiations_out)};
  absl::Status parse_target_args_status =
      internal::ParseTargetArgs(absl::GetFlag(FLAGS_target_args), args);
  absl::StatusOr<Cmdline> cmdline = Cmdline::Create(std::move(args));
  if (!parse_target_args_status.ok() || !cmdline.ok()) {
    return absl::InvalidArgumentError(
        absl::StrCat(cmdline.status().message(), cmdline.ok() ? "" : "\n",
                     parse_target_args_status.message()));
  }
  return cmdline;
}

absl::StatusOr<Cmdline> Cmdline::Create(CmdlineArgs args) {
  std::string error;
  if (args.current_target.empty()) {
    absl::StrAppend(&error, "please specify --target\n");
  }
  if (args.rs_out.empty()) {
    absl::StrAppend(&error, "please specify --rs_out\n");
  }
  if (args.cc_out.empty()) {
    absl::StrAppend(&error, "please specify --cc_out\n");
  }
  if (args.public_headers.empty()) {
    absl::StrAppend(&error, "please specify --public_headers\n");
  }
  if (args.clang_format_exe_path.empty()) {
    absl::StrAppend(&error, "please specify --clang_format_exe_path\n");
  }
  if (args.rustfmt_exe_path.empty()) {
    absl::StrAppend(&error, "please specify --rustfmt_exe_path\n");
  }

  if (args.crubit_support_path_format.empty()) {
    absl::StrAppend(&error, "please specify --crubit_support_path_format\n");
  } else if (!absl::StrContains(args.crubit_support_path_format, "{header}")) {
    absl::StrAppend(
        &error,
        "cannot find `{header}` placeholder in crubit_support_path_format\n");
  }
  if (args.srcs_to_scan_for_instantiations.empty() !=
      args.instantiations_out.empty()) {
    absl::StrAppend(
        &error,
        "please specify both --rust_sources and --instantiations_out when "
        "requesting a template instantiation mode\n");
  }
  for (const HeaderName& header : args.public_headers) {
    if (auto it = args.headers_to_targets.find(header);
        it == args.headers_to_targets.end()) {
      absl::StrAppend(
          &error,
          absl::Substitute(
              "Couldn't find header '$0' in the `headers_to_target` map "
              "derived from the --target_args cmdline argument\n",
              header.IncludePath()));
    }
  }
  if (!error.empty()) {
    error.erase(error.size() - 1);  // remove trailing \n
    return absl::InvalidArgumentError(error);
  }
  return Cmdline(std::move(args));
}

void ExpandParamfiles(int& argc, char**& argv) {
  std::vector<char*> new_argv;  // Will be leaked if we find a paramfile.
  char** begin = argv;
  char** end = begin + argc;
  for (;;) {
    char** next_paramfile =
        std::find_if(begin, end, [](char* c) { return c[0] == '@'; });
    if (next_paramfile == end) break;
    new_argv.insert(new_argv.end(), begin, next_paramfile);
    begin = next_paramfile + 1;
    const char* paramfile = *next_paramfile + 1;
    std::ifstream in(paramfile);
    std::stringstream ss;
    ss << in.rdbuf();
    std::string s = ss.str();
    std::string next_arg;
    // Unfortunately, we can't just use something like StrReplaceAll, because an
    // escaped newline should be part of the value, while an unescaped newline
    // should not be.
    for (auto it = s.begin(); it != s.end(); ++it) {
      if (*it == '\\') {
        ++it;
        if (it == s.end()) {
          absl::StrAppend(&next_arg, "\\");
          break;
        } else {
          absl::StrAppend(&next_arg, absl::string_view(&*it, 1));
        }
      } else if (*it == '\n') {
        new_argv.push_back(
            absl::IgnoreLeak(new auto(std::move(next_arg)))->data());
        next_arg.clear();
      } else {
        absl::StrAppend(&next_arg, absl::string_view(&*it, 1));
      }
    }
    if (!next_arg.empty()) {
      new_argv.push_back(
          absl::IgnoreLeak(new auto(std::move(next_arg)))->data());
    }
  }
  if (begin == argv) return;
  new_argv.insert(new_argv.end(), begin, end);
  argv = new_argv.data();
  argc = new_argv.size();
  absl::IgnoreLeak(new auto(std::move(new_argv)));  // nowhere else to put it.
}

void PreprocessTargetArgs(int& argc, char** argv) {
  // TODO(jeanpierreda): Now that flag parsing logic is no longer in a bash script,
  // this should probably skip target_args entirely. (For now, the target_args
  // flag is left in place for compatibility and to avoid test churn.) We put it
  // in the place of the first --target_to_arg flag, because we can't put it at
  // the end, because of `--`.
  char** end = argv + argc;
  static constexpr absl::string_view kTargetToArg = "--target_to_arg";
  char** first_target_to_arg = std::find(argv, end, kTargetToArg);
  if (first_target_to_arg == end) {
    return;
  }
  std::string& target_args =
      *absl::IgnoreLeak(new std::string("--target_args=["));
  bool is_target_arg = true;
  bool is_done = false;
  auto new_end = std::remove_if(first_target_to_arg + 1, end, [&](char* arg) {
    if (is_done) {
      return false;
    }
    if (is_target_arg) {
      absl::StrAppend(&target_args, arg, ",");
      is_target_arg = false;
      return true;
    } else if (arg == kTargetToArg) {
      is_target_arg = true;
      return true;
    } else if (arg == absl::string_view("--")) {
      is_done = true;
      return false;
    } else {
      return false;
    }
  });
  target_args.pop_back();  // remove trailing comma.
  absl::StrAppend(&target_args, "]");
  *first_target_to_arg = target_args.data();
  argc = new_end - argv;
}

}  // namespace crubit
