// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/main/tools/process-wrapper-options.h"

#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <cstring>
#include <memory>
#include <string>
#include <vector>

#include "src/main/tools/logging.h"

struct Options opt;

// Print out a usage error. argc and argv are the argument counter and vector,
// fmt is a format, string for the error message to print.
static void Usage(char *program_name, const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);

  fprintf(stderr, "\nUsage: %s -- command arg1 @args\n", program_name);
  fprintf(
      stderr,
      "\nPossible arguments:\n"
      "  -g/--graceful_sigterm  propagate SIGTERM to the subprocess and delay "
      "the corresponding SIGKILL until --kill_delay has passed\n"
      "  -t/--timeout <timeout>  timeout after which the child process will be "
      "terminated with SIGTERM\n"
      "  -k/--kill_delay <timeout>  in case timeout occurs, how long to wait "
      "before killing the child with SIGKILL\n"
      "  -o/--stdout <file>  redirect stdout to a file\n"
      "  -e/--stderr <file>  redirect stderr to a file\n"
      "  -s/--stats <file>  if set, write stats in protobuf format to a file\n"
      "  -d/--debug  if set, debug info will be printed\n"
      "  --  command to run inside sandbox, followed by arguments\n");
  exit(EXIT_FAILURE);
}

// Parses command line flags from an argv array and puts the results into the
// global `opt` struct.
static void ParseCommandLine(const std::vector<char *> &args) {
  static struct option long_options[] = {
      {"graceful_sigterm", no_argument, 0, 'g'},
      {"timeout", required_argument, 0, 't'},
      {"kill_delay", required_argument, 0, 'k'},
      {"stdout", required_argument, 0, 'o'},
      {"stderr", required_argument, 0, 'e'},
      {"stats", required_argument, 0, 's'},
      {"debug", no_argument, 0, 'd'},
      {0, 0, 0, 0}};
  extern char *optarg;
  extern int optind, optopt;
  int c;

  while ((c = getopt_long(args.size(), args.data(), "+:gt:k:o:e:s:d",
                          long_options, nullptr)) != -1) {
    switch (c) {
      case 'g':
        opt.graceful_sigterm = true;
        break;
      case 't':
        if (sscanf(optarg, "%lf", &opt.timeout_secs) != 1) {
          Usage(args.front(), "Invalid timeout (-t) value: %s", optarg);
        }
        break;
      case 'k':
        if (sscanf(optarg, "%lf", &opt.kill_delay_secs) != 1) {
          Usage(args.front(), "Invalid kill delay (-k) value: %s", optarg);
        }
        break;
      case 'o':
        if (opt.stdout_path.empty()) {
          opt.stdout_path.assign(optarg);
        } else {
          Usage(args.front(),
                "Cannot redirect stdout (-o) to more than one destination.");
        }
        break;
      case 'e':
        if (opt.stderr_path.empty()) {
          opt.stderr_path.assign(optarg);
        } else {
          Usage(args.front(),
                "Cannot redirect stderr (-e) to more than one destination.");
        }
        break;
      case 's':
        if (opt.stats_path.empty()) {
          opt.stats_path.assign(optarg);
        } else {
          Usage(args.front(),
                "Cannot write stats (-s) to more than one destination.");
        }
        break;
      case 'd':
        opt.debug = true;
        break;
      case '?':
        Usage(args.front(), "Unrecognized argument: -%c (%d)", optopt, optind);
        break;
      case ':':
        Usage(args.front(), "Flag -%c requires an argument", optopt);
        break;
    }
  }

  if (optind < static_cast<int>(args.size())) {
    opt.args.assign(args.begin() + optind, args.end());
  }
}

void ParseOptions(int argc, char *argv[]) {
  std::vector<char *> args(argv, argv + argc);

  ParseCommandLine(args);

  if (opt.args.empty()) {
    Usage(args.front(), "No command specified.");
  }

  // argv[] passed to execve() must be a null-terminated array.
  opt.args.push_back(nullptr);
}
