// 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 <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"
      "  -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"
      "  -d/--debug  if set, debug info will be printed\n"
      "  --  command to run inside sandbox, followed by arguments\n");
  exit(EXIT_FAILURE);
}

static void ValidateIsAbsolutePath(char *path, char *program_name, char flag) {
  if (path[0] != '/') {
    Usage(program_name, "The -%c option must be used with absolute paths only.",
          flag);
  }
}

// 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[] = {
      {"timeout", required_argument, 0, 't'},
      {"kill_delay", required_argument, 0, 'k'},
      {"stdout", required_argument, 0, 'o'},
      {"stderr", required_argument, 0, 'e'},
      {"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(), "+:t:k:o:e:d", long_options,
                          nullptr)) != -1) {
    switch (c) {
      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 '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);
}
