// Copyright 2016 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/linux-sandbox-options.h"

#include <errno.h>
#include <sched.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

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

using std::ifstream;
using std::unique_ptr;
using std::vector;

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"
          "  -W <working-dir>  working directory (uses current directory if "
          "not specified)\n"
          "  -T <timeout>  timeout after which the child process will be "
          "terminated with SIGTERM\n"
          "  -t <timeout>  in case timeout occurs, how long to wait before "
          "killing the child with SIGKILL\n"
          "  -i  on receipt of a SIGINT, forward it to the child process as a "
          "SIGTERM first and then as a SIGKILL after the -T timeout\n"
          "  -l <file>  redirect stdout to a file\n"
          "  -L <file>  redirect stderr to a file\n"
          "  -w <file>  make a file or directory writable for the sandboxed "
          "process\n"
          "  -e <dir>  mount an empty tmpfs on a directory\n"
          "  -M/-m <source/target>  directory to mount inside the sandbox\n"
          "    Multiple directories can be specified and each of them will be "
          "mounted readonly.\n"
          "    The -M option specifies which directory to mount, the -m option "
          "specifies where to\n"
          "  -S <file>  if set, write stats in protobuf format to a file\n"
          "  -H  if set, make hostname in the sandbox equal to 'localhost'\n"
          "  -N  if set, a new network namespace will be created\n"
          "  -R  if set, make the uid/gid be root\n"
          "  -U  if set, make the uid/gid be nobody\n"
          "  -D  if set, debug info will be printed\n"
          "  -h <sandbox-dir>  if set, chroot to sandbox-dir and only "
          " mount whats been specified with -M/-m for improved hermeticity. "
          " The working-dir should be a folder inside the sandbox-dir\n"
          "  @FILE  read newline-separated arguments from FILE\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 an
// Options structure passed in as an argument.
static void ParseCommandLine(unique_ptr<vector<char *>> args) {
  extern char *optarg;
  extern int optind, optopt;
  int c;
  bool source_specified = false;

  while ((c = getopt(args->size(), args->data(),
                     ":W:T:t:il:L:w:e:M:m:S:h:HNRUD")) != -1) {
    if (c != 'M' && c != 'm') source_specified = false;
    switch (c) {
      case 'W':
        if (opt.working_dir.empty()) {
          ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
          opt.working_dir.assign(optarg);
        } else {
          Usage(args->front(),
                "Multiple working directories (-W) specified, expected one.");
        }
        break;
      case 'T':
        if (sscanf(optarg, "%d", &opt.timeout_secs) != 1 ||
            opt.timeout_secs < 0) {
          Usage(args->front(), "Invalid timeout (-T) value: %s", optarg);
        }
        break;
      case 't':
        if (sscanf(optarg, "%d", &opt.kill_delay_secs) != 1 ||
            opt.kill_delay_secs < 0) {
          Usage(args->front(), "Invalid kill delay (-t) value: %s", optarg);
        }
        break;
      case 'i':
        opt.sigint_sends_sigterm = true;
        break;
      case 'l':
        if (opt.stdout_path.empty()) {
          opt.stdout_path.assign(optarg);
        } else {
          Usage(args->front(),
                "Cannot redirect stdout to more than one destination.");
        }
        break;
      case 'L':
        if (opt.stderr_path.empty()) {
          opt.stderr_path.assign(optarg);
        } else {
          Usage(args->front(),
                "Cannot redirect stderr to more than one destination.");
        }
        break;
      case 'w':
        ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
        opt.writable_files.emplace_back(optarg);
        break;
      case 'e':
        ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
        opt.tmpfs_dirs.emplace_back(optarg);
        break;
      case 'M':
        ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
        // Add the current source path to both source and target lists
        opt.bind_mount_sources.emplace_back(optarg);
        opt.bind_mount_targets.emplace_back(optarg);
        source_specified = true;
        break;
      case 'm':
        ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
        if (!source_specified) {
          Usage(args->front(),
                "The -m option must be strictly preceded by an -M option.");
        }
        opt.bind_mount_targets.pop_back();
        opt.bind_mount_targets.emplace_back(optarg);
        source_specified = false;
        break;
      case 'S':
        if (opt.stats_path.empty()) {
          opt.stats_path.assign(optarg);
        } else {
          Usage(args->front(),
                "Cannot write stats to more than one destination.");
        }
        break;
      case 'h':
        opt.hermetic = true;
        if (opt.sandbox_root.empty()) {
          std::string sandbox_root(optarg);
          // Make sure that the sandbox_root path has no trailing slash.
          if (sandbox_root.back() == '/') {
            ValidateIsAbsolutePath(optarg, args->front(), static_cast<char>(c));
            opt.sandbox_root.assign(sandbox_root, 0, sandbox_root.length() - 1);
            if (opt.sandbox_root.back() == '/') {
              Usage(args->front(),
                    "Sandbox root path should not have trailing slashes");
            }
          } else {
            opt.sandbox_root.assign(sandbox_root);
          }
        } else {
          Usage(args->front(),
                "Multiple sandbox roots (-s) specified, expected one.");
        }
        break;
      case 'H':
        opt.fake_hostname = true;
        break;
      case 'N':
        opt.create_netns = true;
        break;
      case 'R':
        if (opt.fake_username) {
          Usage(args->front(),
                "The -R option cannot be used at the same time us the -U "
                "option.");
        }
        opt.fake_root = true;
        break;
      case 'U':
        if (opt.fake_root) {
          Usage(args->front(),
                "The -U option cannot be used at the same time us the -R "
                "option.");
        }
        opt.fake_username = true;
        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 (!opt.working_dir.empty() && !opt.sandbox_root.empty() &&
      opt.working_dir.find(opt.sandbox_root) == std::string::npos) {
    Usage(args->front(),
          "working-dir %s (-W) should be a "
          "subdirectory of sandbox-dir %s (-h)",
          opt.working_dir.c_str(), opt.sandbox_root.c_str());
  }
  if (optind < static_cast<int>(args->size())) {
    if (opt.args.empty()) {
      opt.args.assign(args->begin() + optind, args->end());
    } else {
      Usage(args->front(), "Merging commands not supported.");
    }
  }
}

// Expands a single argument, expanding options @filename to read in the content
// of the file and add it to the list of processed arguments.
static unique_ptr<vector<char *>> ExpandArgument(
    unique_ptr<vector<char *>> expanded, char *arg) {
  if (arg[0] == '@') {
    const char *filename = arg + 1;  // strip off the '@'.
    ifstream f(filename);

    if (!f.is_open()) {
      DIE("opening argument file %s failed", filename);
    }

    for (std::string line; std::getline(f, line);) {
      if (line.length() > 0) {
        expanded = ExpandArgument(std::move(expanded), strdup(line.c_str()));
      }
    }

    if (f.bad()) {
      DIE("error while reading from argument file %s", filename);
    }
  } else {
    expanded->push_back(arg);
  }

  return expanded;
}

// Pre-processes an argument list, expanding options @filename to read in the
// content of the file and add it to the list of arguments. Stops expanding
// arguments once it encounters "--".
static unique_ptr<vector<char *>> ExpandArguments(const vector<char *> &args) {
  unique_ptr<vector<char *>> expanded(new vector<char *>());
  expanded->reserve(args.size());
  for (auto arg = args.begin(); arg != args.end(); ++arg) {
    if (strcmp(*arg, "--") != 0) {
      expanded = ExpandArgument(std::move(expanded), *arg);
    } else {
      expanded->insert(expanded->end(), arg, args.end());
      break;
    }
  }
  return expanded;
}

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

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

  if (opt.working_dir.empty()) {
    char *working_dir = getcwd(nullptr, 0);
    if (working_dir == nullptr) {
      DIE("getcwd");
    }
    opt.working_dir = working_dir;
    free(working_dir);
  }
}
