// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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 "util/minidump.h"

#include <assert.h>
#include <boost/filesystem.hpp>
#include <client/linux/handler/exception_handler.h>
#include <common/linux/linux_libc_support.h>
#include <google_breakpad/common/minidump_format.h>
#include <third_party/lss/linux_syscall_support.h>
#include <ctime>
#include <fstream>
#include <glob.h>
#include <iomanip>
#include <map>
#include <signal.h>
#include <sstream>

#include "common/logging.h"
#include "common/version.h"
#include "util/filesystem-util.h"
#include "util/time.h"

using namespace std;

using boost::filesystem::create_directories;
using boost::filesystem::is_regular_file;
using boost::filesystem::path;
using boost::filesystem::remove;

DECLARE_string(log_dir);
DECLARE_bool(enable_minidumps);
DECLARE_string(minidump_path);
DECLARE_int32(max_minidumps);
DECLARE_int32(minidump_size_limit_hint_kb);

namespace impala {

/// Breakpad ExceptionHandler. It registers its own signal handlers to write minidump
/// files during process crashes, but also can be used to write minidumps directly.
static google_breakpad::ExceptionHandler* minidump_exception_handler = NULL;

/// Test helper. True if minidumps should be enabled.
static bool minidumps_enabled = true;

/// Called by the exception handler before minidump is produced. Minidump is only written
/// if this returns true.
static bool FilterCallback(void* context) {
  return minidumps_enabled;
}

/// Callback for breakpad. It is called by breakpad whenever a minidump file has been
/// written and should not be called directly. It logs the event before breakpad crashes
/// the process. Due to the process being in a failed state we write to stdout/stderr and
/// let the surrounding redirection make sure the output gets logged. The calls might
/// still fail in unknown scenarios as the process is in a broken state. However we don't
/// rely on them as the minidump file has been written already.
static bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
    void* context, bool succeeded) {
  // See if a file was written successfully.
  if (succeeded) {
    // Write message to stdout/stderr, which will usually be captured in the INFO/ERROR
    // log.
    const char msg[] = "Wrote minidump to ";
    const int msg_len = sizeof(msg) / sizeof(msg[0]) - 1;
    const char* path = descriptor.path();
    // We use breakpad's reimplementation of strlen to avoid calling into libc.
    const int path_len = my_strlen(path);
    // We use the linux syscall support methods from chromium here as per the
    // recommendation of the breakpad docs to avoid calling into other shared libraries.
    sys_write(STDOUT_FILENO, msg, msg_len);
    sys_write(STDOUT_FILENO, path, path_len);
    sys_write(STDOUT_FILENO, "\n", 1);
    sys_write(STDERR_FILENO, msg, msg_len);
    sys_write(STDERR_FILENO, path, path_len);
    sys_write(STDERR_FILENO, "\n", 1);
  }
  // Return the value received in the call as described in the minidump documentation. If
  // this values is true, then no other handlers will be called. Breakpad will still crash
  // the process.
  return succeeded;
}

/// Signal handler to write a minidump file outside of crashes.
static void HandleSignal(int signum, siginfo_t* info, void* context) {
  const char* msg = "Caught signal: SIGUSR1\n";
  sys_write(STDOUT_FILENO, msg, strlen(msg));
  minidump_exception_handler->WriteMinidump(FLAGS_minidump_path, DumpCallback, NULL);
}

/// Register our signal handler to write minidumps on SIGUSR1. Will make us ignore the
/// signal if 'minidumps_enabled' is false.
static void SetupSigUSR1Handler(bool minidumps_enabled) {
  struct sigaction sig_action;
  memset(&sig_action, 0, sizeof(sig_action));
  sigemptyset(&sig_action.sa_mask);
  if (minidumps_enabled) {
    DCHECK(minidump_exception_handler != NULL);
    sig_action.sa_sigaction = &HandleSignal;
    sig_action.sa_flags = SA_SIGINFO;
  } else {
    sig_action.sa_handler = SIG_IGN;
  }
  if (sigaction(SIGUSR1, &sig_action, nullptr) == -1) {
    stringstream error_msg;
    error_msg << "Failed to register action for SIGUSR1: " << GetStrErrMsg();
    CLEAN_EXIT_WITH_ERROR(error_msg.str());
  }
}

void CheckAndRotateMinidumps(int max_minidumps) {
  // Disable rotation if 0 or wrong input
  if (max_minidumps <= 0) return;

  // Search for minidumps. There could be multiple minidumps for a single second.
  multimap<int, path> timestamp_to_path;
  // Minidump filenames are created by breakpad in the following format, for example:
  // 7b57915b-ee6a-dbc5-21e59491-5c60a2cf.dmp.
  string pattern = FLAGS_minidump_path + "/*.dmp";
  glob_t result;
  glob(pattern.c_str(), GLOB_TILDE, NULL, &result);
  for (size_t i = 0; i < result.gl_pathc; ++i) {
    const path minidump_path(result.gl_pathv[i]);
    boost::system::error_code err;
    bool is_file = is_regular_file(minidump_path, err);
    // is_regular_file() calls stat() eventually, which can return errors, e.g. if the
    // file permissions prevented access or the path was wrong (see 'man 2 stat' for
    // details). In these cases we assume that the issue is out of our control and err on
    // the safe side by keeping the minidump around, hoping it will aid in debugging the
    // issue. The alternative, removing a ~2MB file, will probably not help much anyways.
    if (err) {
      LOG(WARNING) << "Failed to stat() file " << minidump_path << ": " << err;
      continue;
    }
    if (is_file) {
      ifstream stream(minidump_path.c_str(), std::ios::in | std::ios::binary);
      if (!stream.good()) {
        // Error opening file, probably broken, remove it.
        LOG(WARNING) << "Failed to open file " << minidump_path << ". Removing it.";
        stream.close();
        // Best effort, ignore error.
        remove(minidump_path.c_str(), err);
        continue;
      }
      // Read minidump header from file.
      MDRawHeader header;
      constexpr int header_size = sizeof(header);
      stream.read((char *)(&header), header_size);
      // Check for minidump header signature and version. We don't need to check for
      // endianness issues here since the file was written on the same machine. Ignore the
      // higher 16 bit of the version as per a comment in the breakpad sources.
      if (stream.gcount() != header_size || header.signature != MD_HEADER_SIGNATURE ||
          (header.version & 0x0000ffff) != MD_HEADER_VERSION) {
        LOG(WARNING) << "Found file in minidump folder, but it does not look like a "
            << "minidump file: " << minidump_path.string() << ". Removing it.";
        remove(minidump_path, err);
        if (err) {
          LOG(ERROR) << "Failed to delete file: " << minidump_path << "(error was: "
              << err << ")";
        }
        continue;
      }
      int timestamp = header.time_date_stamp;
      timestamp_to_path.emplace(timestamp, minidump_path);
    }
  }
  globfree(&result);

  // Remove oldest entries until max_minidumps are left.
  if (timestamp_to_path.size() <= max_minidumps) return;
  int files_to_delete = timestamp_to_path.size() - max_minidumps;
  DCHECK_GT(files_to_delete, 0);
  auto to_delete = timestamp_to_path.begin();
  for (int i = 0; i < files_to_delete; ++i, ++to_delete) {
    boost::system::error_code err;
    remove(to_delete->second, err);
    if (!err) {
      LOG(INFO) << "Removed old minidump file : " << to_delete->second;
    } else {
      LOG(ERROR) << "Failed to delete old minidump file: " << to_delete->second <<
        "(error was: " << err << ")";
    }
  }
}

Status RegisterMinidump(const char* cmd_line_path) {
  // Registration must only be called once.
  static bool registered = false;
  DCHECK(!registered);
  registered = true;

  if (!FLAGS_enable_minidumps || FLAGS_minidump_path.empty()) {
    SetupSigUSR1Handler(false);
    return Status::OK();
  }

  if (path(FLAGS_minidump_path).is_relative()) {
    path log_dir(FLAGS_log_dir);
    FLAGS_minidump_path = (log_dir / FLAGS_minidump_path).string();
  }

  // Add the daemon name to the path where minidumps will be written. This makes
  // identification easier and prevents name collisions between the files.
  path daemon = path(cmd_line_path).filename();
  FLAGS_minidump_path = (FLAGS_minidump_path / daemon).string();

  // Create the directory if it is not there. The minidump doesn't get written if there is
  // no directory.
  boost::system::error_code err;
  create_directories(FLAGS_minidump_path, err);
  if (err) {
    stringstream ss;
    ss << "Could not create minidump folder " << FLAGS_minidump_path << ". Error "
        << "was: " << err;
    return Status(ss.str());
  }

  google_breakpad::MinidumpDescriptor desc(FLAGS_minidump_path.c_str());

  // Limit filesize if configured.
  if (FLAGS_minidump_size_limit_hint_kb > 0) {
    size_t size_limit = 1024 * static_cast<int64_t>(FLAGS_minidump_size_limit_hint_kb);
    LOG(INFO) << "Setting minidump size limit to " << size_limit << ".";
    desc.set_size_limit(size_limit);
  }

  // Intentionally leaked. We want this to have the lifetime of the process.
  DCHECK(minidump_exception_handler == NULL);
  minidump_exception_handler = new google_breakpad::ExceptionHandler(
      desc, FilterCallback, DumpCallback, NULL, true, -1);

  // Setup signal handler for SIGUSR1.
  SetupSigUSR1Handler(true);

  return Status::OK();
}

bool EnableMinidumpsForTest(bool enabled) {
  bool old_value = minidumps_enabled;
  minidumps_enabled = enabled;
  return old_value;
}

}  // end ns impala
