// Copyright 2015 The Crashpad 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 <errno.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <time.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/check_op.h"
#include "base/files/file_path.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "client/crash_report_database.h"
#include "client/settings.h"
#include "tools/tool_support.h"
#include "util/file/file_io.h"
#include "util/file/file_reader.h"
#include "util/misc/uuid.h"
#include "util/stdlib/string_number_conversion.h"

namespace crashpad {
namespace {

void Usage(const base::FilePath& me) {
  fprintf(stderr,
"Usage: %" PRFilePath " [OPTION]... PID\n"
"Operate on Crashpad crash report databases.\n"
"\n"
"      --create                    allow database at PATH to be created\n"
"  -d, --database=PATH             operate on the crash report database at PATH\n"
"      --show-client-id            show the client ID\n"
"      --show-uploads-enabled      show whether uploads are enabled\n"
"      --show-last-upload-attempt-time\n"
"                                  show the last-upload-attempt time\n"
"      --show-pending-reports      show reports eligible for upload\n"
"      --show-completed-reports    show reports not eligible for upload\n"
"      --show-all-report-info      with --show-*-reports, show more information\n"
"      --show-report=UUID          show report stored under UUID\n"
"      --set-uploads-enabled=BOOL  enable or disable uploads\n"
"      --set-last-upload-attempt-time=TIME\n"
"                                  set the last-upload-attempt time to TIME\n"
"      --new-report=PATH           submit a new report at PATH, or - for stdin\n"
"      --utc                       show and set UTC times instead of local\n"
"      --help                      display this help and exit\n"
"      --version                   output version information and exit\n",
          me.value().c_str());
  ToolSupport::UsageTail(me);
}

struct Options {
  std::vector<UUID> show_reports;
  std::vector<base::FilePath> new_report_paths;
  const char* database;
  const char* set_last_upload_attempt_time_string;
  time_t set_last_upload_attempt_time;
  bool create;
  bool show_client_id;
  bool show_uploads_enabled;
  bool show_last_upload_attempt_time;
  bool show_pending_reports;
  bool show_completed_reports;
  bool show_all_report_info;
  bool set_uploads_enabled;
  bool has_set_uploads_enabled;
  bool utc;
};

// Converts |string| to |boolean|, returning true if a conversion could be
// performed, and false without setting |boolean| if no conversion could be
// performed. Various string representations of a boolean are recognized
// case-insensitively.
bool StringToBool(const char* string, bool* boolean) {
  static constexpr const char* kFalseWords[] = {
      "0",
      "false",
      "no",
      "off",
      "disabled",
      "clear",
  };
  static constexpr const char* kTrueWords[] = {
      "1",
      "true",
      "yes",
      "on",
      "enabled",
      "set",
  };

  for (size_t index = 0; index < base::size(kFalseWords); ++index) {
    if (strcasecmp(string, kFalseWords[index]) == 0) {
      *boolean = false;
      return true;
    }
  }

  for (size_t index = 0; index < base::size(kTrueWords); ++index) {
    if (strcasecmp(string, kTrueWords[index]) == 0) {
      *boolean = true;
      return true;
    }
  }

  return false;
}

// Converts |boolean| to a string, either "true" or "false".
std::string BoolToString(bool boolean) {
  return std::string(boolean ? "true" : "false");
}

// Converts |string| to |out_time|, returning true if a conversion could be
// performed, and false without setting |boolean| if no conversion could be
// performed. Various time formats are recognized, including several string
// representations and a numeric time_t representation. The special |string|
// "never" is recognized as converted to a |out_time| value of 0; "now" is
// converted to the current time. |utc|, when true, causes |string| to be
// interpreted as a UTC time rather than a local time when the time zone is
// ambiguous.
bool StringToTime(const char* string, time_t* out_time, bool utc) {
  if (strcasecmp(string, "never") == 0) {
    *out_time = 0;
    return true;
  }

  if (strcasecmp(string, "now") == 0) {
    errno = 0;
    PCHECK(time(out_time) != -1 || errno == 0);
    return true;
  }

  const char* end = string + strlen(string);

  static constexpr const char* kFormats[] = {
      "%Y-%m-%d %H:%M:%S %Z",
      "%Y-%m-%d %H:%M:%S",
      "%+",
  };

  for (size_t index = 0; index < base::size(kFormats); ++index) {
    tm time_tm;
    const char* strptime_result = strptime(string, kFormats[index], &time_tm);
    if (strptime_result == end) {
      time_t test_out_time;
      if (utc) {
        test_out_time = timegm(&time_tm);
      } else {
        test_out_time = mktime(&time_tm);
      }

      // mktime() is supposed to set errno in the event of an error, but support
      // for this is spotty, so there’s no way to distinguish between a true
      // time_t of -1 (1969-12-31 23:59:59 UTC) and an error. Assume error.
      //
      // See 10.11.5 Libc-1082.50.1/stdtime/FreeBSD/localtime.c and
      // glibc-2.24/time/mktime.c, which don’t set errno or save and restore
      // errno. Post-Android 7.1.0 Bionic is even more hopeless, setting errno
      // whenever the time conversion returns -1, even for valid input. See
      // libc/tzcode/localtime.c mktime(). Windows seems to get it right: see
      // 10.0.14393 SDK Source/ucrt/time/mktime.cpp.
      if (test_out_time != -1) {
        *out_time = test_out_time;
        return true;
      }
    }
  }

  int64_t int64_result;
  if (StringToNumber(string, &int64_result) &&
      base::IsValueInRangeForNumericType<time_t>(int64_result)) {
    *out_time = int64_result;
    return true;
  }

  return false;
}

// Converts |out_time| to a string, and returns it. |utc| determines whether the
// converted time will reference local time or UTC. If |out_time| is 0, the
// string "never" will be returned as a special case.
std::string TimeToString(time_t out_time, bool utc) {
  if (out_time == 0) {
    return std::string("never");
  }

  tm time_tm;
  if (utc) {
    PCHECK(gmtime_r(&out_time, &time_tm));
  } else {
    PCHECK(localtime_r(&out_time, &time_tm));
  }

  char string[64];
  CHECK_NE(
      strftime(string, base::size(string), "%Y-%m-%d %H:%M:%S %Z", &time_tm),
      0u);

  return std::string(string);
}

// Shows information about a single |report|. |space_count| is the number of
// spaces to print before each line that is printed. |utc| determines whether
// times should be shown in UTC or the local time zone.
void ShowReport(const CrashReportDatabase::Report& report,
                size_t space_count,
                bool utc) {
  std::string spaces(space_count, ' ');

  printf("%sPath: %" PRFilePath "\n",
         spaces.c_str(),
         report.file_path.value().c_str());
  if (!report.id.empty()) {
    printf("%sRemote ID: %s\n", spaces.c_str(), report.id.c_str());
  }
  printf("%sCreation time: %s\n",
         spaces.c_str(),
         TimeToString(report.creation_time, utc).c_str());
  printf("%sUploaded: %s\n",
         spaces.c_str(),
         BoolToString(report.uploaded).c_str());
  printf("%sLast upload attempt time: %s\n",
         spaces.c_str(),
         TimeToString(report.last_upload_attempt_time, utc).c_str());
  printf("%sUpload attempts: %d\n", spaces.c_str(), report.upload_attempts);
}

// Shows information about a vector of |reports|. |space_count| is the number of
// spaces to print before each line that is printed. |options| will be consulted
// to determine whether to show expanded information
// (options.show_all_report_info) and what time zone to use when showing
// expanded information (options.utc).
void ShowReports(const std::vector<CrashReportDatabase::Report>& reports,
                 size_t space_count,
                 const Options& options) {
  std::string spaces(space_count, ' ');
  const char* colon = options.show_all_report_info ? ":" : "";

  for (const CrashReportDatabase::Report& report : reports) {
    printf("%s%s%s\n", spaces.c_str(), report.uuid.ToString().c_str(), colon);
    if (options.show_all_report_info) {
      ShowReport(report, space_count + 2, options.utc);
    }
  }
}

int DatabaseUtilMain(int argc, char* argv[]) {
  const base::FilePath argv0(
      ToolSupport::CommandLineArgumentToFilePathStringType(argv[0]));
  const base::FilePath me(argv0.BaseName());

  enum OptionFlags {
    // “Short” (single-character) options.
    kOptionDatabase = 'd',

    // Long options without short equivalents.
    kOptionLastChar = 255,
    kOptionCreate,
    kOptionShowClientID,
    kOptionShowUploadsEnabled,
    kOptionShowLastUploadAttemptTime,
    kOptionShowPendingReports,
    kOptionShowCompletedReports,
    kOptionShowAllReportInfo,
    kOptionShowReport,
    kOptionSetUploadsEnabled,
    kOptionSetLastUploadAttemptTime,
    kOptionNewReport,
    kOptionUTC,

    // Standard options.
    kOptionHelp = -2,
    kOptionVersion = -3,
  };

  static constexpr option long_options[] = {
      {"create", no_argument, nullptr, kOptionCreate},
      {"database", required_argument, nullptr, kOptionDatabase},
      {"show-client-id", no_argument, nullptr, kOptionShowClientID},
      {"show-uploads-enabled", no_argument, nullptr, kOptionShowUploadsEnabled},
      {"show-last-upload-attempt-time",
       no_argument,
       nullptr,
       kOptionShowLastUploadAttemptTime},
      {"show-pending-reports", no_argument, nullptr, kOptionShowPendingReports},
      {"show-completed-reports",
       no_argument,
       nullptr,
       kOptionShowCompletedReports},
      {"show-all-report-info", no_argument, nullptr, kOptionShowAllReportInfo},
      {"show-report", required_argument, nullptr, kOptionShowReport},
      {"set-uploads-enabled",
       required_argument,
       nullptr,
       kOptionSetUploadsEnabled},
      {"set-last-upload-attempt-time",
       required_argument,
       nullptr,
       kOptionSetLastUploadAttemptTime},
      {"new-report", required_argument, nullptr, kOptionNewReport},
      {"utc", no_argument, nullptr, kOptionUTC},
      {"help", no_argument, nullptr, kOptionHelp},
      {"version", no_argument, nullptr, kOptionVersion},
      {nullptr, 0, nullptr, 0},
  };

  Options options = {};

  int opt;
  while ((opt = getopt_long(argc, argv, "d:", long_options, nullptr)) != -1) {
    switch (opt) {
      case kOptionCreate: {
        options.create = true;
        break;
      }
      case kOptionDatabase: {
        options.database = optarg;
        break;
      }
      case kOptionShowClientID: {
        options.show_client_id = true;
        break;
      }
      case kOptionShowUploadsEnabled: {
        options.show_uploads_enabled = true;
        break;
      }
      case kOptionShowLastUploadAttemptTime: {
        options.show_last_upload_attempt_time = true;
        break;
      }
      case kOptionShowPendingReports: {
        options.show_pending_reports = true;
        break;
      }
      case kOptionShowCompletedReports: {
        options.show_completed_reports = true;
        break;
      }
      case kOptionShowAllReportInfo: {
        options.show_all_report_info = true;
        break;
      }
      case kOptionShowReport: {
        UUID uuid;
        if (!uuid.InitializeFromString(optarg)) {
          ToolSupport::UsageHint(me, "--show-report requires a UUID");
          return EXIT_FAILURE;
        }
        options.show_reports.push_back(uuid);
        break;
      }
      case kOptionSetUploadsEnabled: {
        if (!StringToBool(optarg, &options.set_uploads_enabled)) {
          ToolSupport::UsageHint(me, "--set-uploads-enabled requires a BOOL");
          return EXIT_FAILURE;
        }
        options.has_set_uploads_enabled = true;
        break;
      }
      case kOptionSetLastUploadAttemptTime: {
        options.set_last_upload_attempt_time_string = optarg;
        break;
      }
      case kOptionNewReport: {
        options.new_report_paths.push_back(base::FilePath(
            ToolSupport::CommandLineArgumentToFilePathStringType(optarg)));
        break;
      }
      case kOptionUTC: {
        options.utc = true;
        break;
      }
      case kOptionHelp: {
        Usage(me);
        return EXIT_SUCCESS;
      }
      case kOptionVersion: {
        ToolSupport::Version(me);
        return EXIT_SUCCESS;
      }
      default: {
        ToolSupport::UsageHint(me, nullptr);
        return EXIT_FAILURE;
      }
    }
  }
  argc -= optind;
  argv += optind;

  if (!options.database) {
    ToolSupport::UsageHint(me, "--database is required");
    return EXIT_FAILURE;
  }

  // This conversion couldn’t happen in the option-processing loop above because
  // it depends on options.utc, which may have been set after
  // options.set_last_upload_attempt_time_string.
  if (options.set_last_upload_attempt_time_string) {
    if (!StringToTime(options.set_last_upload_attempt_time_string,
                      &options.set_last_upload_attempt_time,
                      options.utc)) {
      ToolSupport::UsageHint(me,
                             "--set-last-upload-attempt-time requires a TIME");
      return EXIT_FAILURE;
    }
  }

  // --new-report is treated as a show operation because it produces output.
  const size_t show_operations = options.show_client_id +
                                 options.show_uploads_enabled +
                                 options.show_last_upload_attempt_time +
                                 options.show_pending_reports +
                                 options.show_completed_reports +
                                 options.show_reports.size() +
                                 options.new_report_paths.size();
  const size_t set_operations =
      options.has_set_uploads_enabled +
      (options.set_last_upload_attempt_time_string != nullptr);

  if ((options.create ? 1 : 0) + show_operations + set_operations == 0) {
    ToolSupport::UsageHint(me, "nothing to do");
    return EXIT_FAILURE;
  }

  std::unique_ptr<CrashReportDatabase> database;
  base::FilePath database_path = base::FilePath(
      ToolSupport::CommandLineArgumentToFilePathStringType(options.database));
  if (options.create) {
    database = CrashReportDatabase::Initialize(database_path);
  } else {
    database = CrashReportDatabase::InitializeWithoutCreating(database_path);
  }
  if (!database) {
    return EXIT_FAILURE;
  }

  Settings* settings = database->GetSettings();

  // Handle the “show” options before the “set” options so that when they’re
  // specified together, the “show” option reflects the initial state.

  if (options.show_client_id) {
    UUID client_id;
    if (!settings->GetClientID(&client_id)) {
      return EXIT_FAILURE;
    }

    const char* prefix = (show_operations > 1) ? "Client ID: " : "";

    printf("%s%s\n", prefix, client_id.ToString().c_str());
  }

  if (options.show_uploads_enabled) {
    bool uploads_enabled;
    if (!settings->GetUploadsEnabled(&uploads_enabled)) {
      return EXIT_FAILURE;
    }

    const char* prefix = (show_operations > 1) ? "Uploads enabled: " : "";

    printf("%s%s\n", prefix, BoolToString(uploads_enabled).c_str());
  }

  if (options.show_last_upload_attempt_time) {
    time_t last_upload_attempt_time;
    if (!settings->GetLastUploadAttemptTime(&last_upload_attempt_time)) {
      return EXIT_FAILURE;
    }

    const char* prefix =
        (show_operations > 1) ? "Last upload attempt time: " : "";

    printf("%s%s (%ld)\n",
           prefix,
           TimeToString(last_upload_attempt_time, options.utc).c_str(),
           static_cast<long>(last_upload_attempt_time));
  }

  if (options.show_pending_reports) {
    std::vector<CrashReportDatabase::Report> pending_reports;
    if (database->GetPendingReports(&pending_reports) !=
        CrashReportDatabase::kNoError) {
      return EXIT_FAILURE;
    }

    if (show_operations > 1) {
      printf("Pending reports:\n");
    }

    ShowReports(pending_reports, show_operations > 1 ? 2 : 0, options);
  }

  if (options.show_completed_reports) {
    std::vector<CrashReportDatabase::Report> completed_reports;
    if (database->GetCompletedReports(&completed_reports) !=
        CrashReportDatabase::kNoError) {
      return EXIT_FAILURE;
    }

    if (show_operations > 1) {
      printf("Completed reports:\n");
    }

    ShowReports(completed_reports, show_operations > 1 ? 2 : 0, options);
  }

  for (const UUID& uuid : options.show_reports) {
    CrashReportDatabase::Report report;
    CrashReportDatabase::OperationStatus status =
        database->LookUpCrashReport(uuid, &report);
    if (status == CrashReportDatabase::kNoError) {
      if (show_operations > 1) {
        printf("Report %s:\n", uuid.ToString().c_str());
      }
      ShowReport(report, show_operations > 1 ? 2 : 0, options.utc);
    } else if (status == CrashReportDatabase::kReportNotFound) {
      // If only asked to do one thing, a failure to find the single requested
      // report should result in a failure exit status.
      if (show_operations + set_operations == 1) {
        fprintf(
            stderr, "%" PRFilePath ": Report not found\n", me.value().c_str());
        return EXIT_FAILURE;
      }
      printf("Report %s not found\n", uuid.ToString().c_str());
    } else {
      return EXIT_FAILURE;
    }
  }

  if (options.has_set_uploads_enabled &&
      !settings->SetUploadsEnabled(options.set_uploads_enabled)) {
    return EXIT_FAILURE;
  }

  if (options.set_last_upload_attempt_time_string &&
      !settings->SetLastUploadAttemptTime(
          options.set_last_upload_attempt_time)) {
    return EXIT_FAILURE;
  }

  bool used_stdin = false;
  for (const base::FilePath& new_report_path : options.new_report_paths) {
    std::unique_ptr<FileReaderInterface> file_reader;

    if (new_report_path.value() == FILE_PATH_LITERAL("-")) {
      if (used_stdin) {
        fprintf(stderr,
                "%" PRFilePath
                ": Only one --new-report may be read from standard input\n",
                me.value().c_str());
        return EXIT_FAILURE;
      }
      used_stdin = true;
      file_reader.reset(new WeakFileHandleFileReader(
          StdioFileHandle(StdioStream::kStandardInput)));
    } else {
      std::unique_ptr<FileReader> file_path_reader(new FileReader());
      if (!file_path_reader->Open(new_report_path)) {
        return EXIT_FAILURE;
      }

      file_reader = std::move(file_path_reader);
    }

    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
    CrashReportDatabase::OperationStatus status =
        database->PrepareNewCrashReport(&new_report);
    if (status != CrashReportDatabase::kNoError) {
      return EXIT_FAILURE;
    }

    char buf[4096];
    FileOperationResult read_result;
    do {
      read_result = file_reader->Read(buf, sizeof(buf));
      if (read_result < 0) {
        return EXIT_FAILURE;
      }
      if (read_result > 0 && !new_report->Writer()->Write(buf, read_result)) {
        return EXIT_FAILURE;
      }
    } while (read_result > 0);

    UUID uuid;
    status = database->FinishedWritingCrashReport(std::move(new_report), &uuid);
    if (status != CrashReportDatabase::kNoError) {
      return EXIT_FAILURE;
    }

    const char* prefix = (show_operations > 1) ? "New report ID: " : "";
    printf("%s%s\n", prefix, uuid.ToString().c_str());
  }

  return EXIT_SUCCESS;
}

}  // namespace
}  // namespace crashpad

#if defined(OS_POSIX)
int main(int argc, char* argv[]) {
  return crashpad::DatabaseUtilMain(argc, argv);
}
#elif defined(OS_WIN)
int wmain(int argc, wchar_t* argv[]) {
  return crashpad::ToolSupport::Wmain(argc, argv, crashpad::DatabaseUtilMain);
}
#endif  // OS_POSIX
