// 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 "kudu/server/pprof-path-handlers.h"

#include <fstream>
#include <glog/logging.h>
#include <gperftools/heap-profiler.h>
#include <gperftools/malloc_extension.h>
#include <gperftools/profiler.h>
#include <string>
#include <sys/stat.h>
#include <vector>

#include "kudu/gutil/map-util.h"
#include "kudu/gutil/strings/numbers.h"
#include "kudu/gutil/strings/split.h"
#include "kudu/gutil/strings/stringpiece.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/gutil/sysinfo.h"
#include "kudu/server/webserver.h"
#include "kudu/util/env.h"
#include "kudu/util/logging.h"
#include "kudu/util/monotime.h"
#include "kudu/util/spinlock_profiling.h"
#include "kudu/util/status.h"

DECLARE_bool(enable_process_lifetime_heap_profiling);
DECLARE_string(heap_profile_path);


using std::endl;
using std::ifstream;
using std::ostringstream;
using std::string;
using std::stringstream;

// GLog already implements symbolization. Just import their hidden symbol.
namespace google {
// Symbolizes a program counter.  On success, returns true and write the
// symbol name to "out".  The symbol name is demangled if possible
// (supports symbols generated by GCC 3.x or newer).  Otherwise,
// returns false.
bool Symbolize(void *pc, char *out, int out_size);
}

namespace kudu {

const int PPROF_DEFAULT_SAMPLE_SECS = 30; // pprof default sample time in seconds.

// pprof asks for the url /pprof/cmdline to figure out what application it's profiling.
// The server should respond by sending the executable path.
static void PprofCmdLineHandler(const Webserver::WebRequest& req, stringstream* output) {
  string executable_path;
  Env* env = Env::Default();
  WARN_NOT_OK(env->GetExecutablePath(&executable_path), "Failed to get executable path");
  *output << executable_path;
}

// pprof asks for the url /pprof/heap to get heap information. This should be implemented
// by calling HeapProfileStart(filename), continue to do work, and then, some number of
// seconds later, call GetHeapProfile() followed by HeapProfilerStop().
static void PprofHeapHandler(const Webserver::WebRequest& req, stringstream* output) {
#ifndef TCMALLOC_ENABLED
  (*output) << "Heap profiling is not available without tcmalloc.";
#else
  // Remote (on-demand) profiling is disabled if the process is already being profiled.
  if (FLAGS_enable_process_lifetime_heap_profiling) {
    (*output) << "Heap profiling is running for the process lifetime.";
    return;
  }

  auto it = req.parsed_args.find("seconds");
  int seconds = PPROF_DEFAULT_SAMPLE_SECS;
  if (it != req.parsed_args.end()) {
    seconds = atoi(it->second.c_str());
  }

  HeapProfilerStart(FLAGS_heap_profile_path.c_str());
  // Sleep to allow for some samples to be collected.
  SleepFor(MonoDelta::FromSeconds(seconds));
  const char* profile = GetHeapProfile();
  HeapProfilerStop();
  (*output) << profile;
  delete profile;
#endif
}

// pprof asks for the url /pprof/profile?seconds=XX to get cpu-profiling information.
// The server should respond by calling ProfilerStart(), continuing to do its work,
// and then, XX seconds later, calling ProfilerStop().
static void PprofCpuProfileHandler(const Webserver::WebRequest& req, stringstream* output) {
#ifndef TCMALLOC_ENABLED
  (*output) << "CPU profiling is not available without tcmalloc.";
#else
  auto it = req.parsed_args.find("seconds");
  int seconds = PPROF_DEFAULT_SAMPLE_SECS;
  if (it != req.parsed_args.end()) {
    seconds = atoi(it->second.c_str());
  }
  // Build a temporary file name that is hopefully unique.
  string tmp_prof_file_name = strings::Substitute("/tmp/kudu_cpu_profile/$0.$1", getpid(), rand());
  ProfilerStart(tmp_prof_file_name.c_str());
  SleepFor(MonoDelta::FromSeconds(seconds));
  ProfilerStop();
  ifstream prof_file(tmp_prof_file_name.c_str(), std::ios::in);
  if (!prof_file.is_open()) {
    (*output) << "Unable to open cpu profile: " << tmp_prof_file_name;
    return;
  }
  (*output) << prof_file.rdbuf();
  prof_file.close();
#endif
}

// pprof asks for the url /pprof/growth to get heap-profiling delta (growth) information.
// The server should respond by calling:
// MallocExtension::instance()->GetHeapGrowthStacks(&output);
static void PprofGrowthHandler(const Webserver::WebRequest& req, stringstream* output) {
#ifndef TCMALLOC_ENABLED
  (*output) << "Growth profiling is not available without tcmalloc.";
#else
  string heap_growth_stack;
  MallocExtension::instance()->GetHeapGrowthStacks(&heap_growth_stack);
  (*output) << heap_growth_stack;
#endif
}

// Lock contention profiling
static void PprofContentionHandler(const Webserver::WebRequest& req, stringstream* output) {
  string secs_str = FindWithDefault(req.parsed_args, "seconds", "");
  int32_t seconds = ParseLeadingInt32Value(secs_str.c_str(), PPROF_DEFAULT_SAMPLE_SECS);
  int64_t discarded_samples = 0;

  *output << "--- contention" << endl;
  *output << "sampling period = 1" << endl;
  *output << "cycles/second = " << base::CyclesPerSecond() << endl;

  MonoTime end = MonoTime::Now(MonoTime::FINE);
  end.AddDelta(MonoDelta::FromSeconds(seconds));
  StartSynchronizationProfiling();
  while (MonoTime::Now(MonoTime::FINE).ComesBefore(end)) {
    SleepFor(MonoDelta::FromMilliseconds(500));
    FlushSynchronizationProfile(output, &discarded_samples);
  }
  StopSynchronizationProfiling();
  FlushSynchronizationProfile(output, &discarded_samples);

  // pprof itself ignores this value, but we can at least look at it in the textual
  // output.
  *output << "discarded samples = " << discarded_samples << std::endl;

#if defined(__linux__)
  // procfs only exists on Linux.
  faststring maps;
  ReadFileToString(Env::Default(), "/proc/self/maps", &maps);
  *output << maps.ToString();
#endif // defined(__linux__)
}


// pprof asks for the url /pprof/symbol to map from hex addresses to variable names.
// When the server receives a GET request for /pprof/symbol, it should return a line
// formatted like: num_symbols: ###
// where ### is the number of symbols found in the binary. For now, the only important
// distinction is whether the value is 0, which it is for executables that lack debug
// information, or not-0).
//
// In addition to the GET request for this url, the server must accept POST requests.
// This means that after the HTTP headers, pprof will pass in a list of hex addresses
// connected by +, like:
//   curl -d '0x0824d061+0x0824d1cf' http://remote_host:80/pprof/symbol
// The server should read the POST data, which will be in one line, and for each hex value
// should write one line of output to the output stream, like so:
// <hex address><tab><function name>
// For instance:
// 0x08b2dabd    _Update
static void PprofSymbolHandler(const Webserver::WebRequest& req, stringstream* output) {
  if (req.request_method == "GET") {
    // Per the above comment, pprof doesn't expect to know the actual number of symbols.
    // Any non-zero value indicates that we support symbol lookup.
    (*output) << "num_symbols: 1";
    return;
  }

  int missing_symbols = 0;
  int invalid_addrs = 0;

  // Symbolization request.
  vector<StringPiece> pieces = strings::Split(req.post_data, "+");
  for (StringPiece p : pieces) {
    string hex_addr;
    if (!TryStripPrefixString(p, "0x", &hex_addr)) {
      invalid_addrs++;
      continue;
    }
    uint64_t addr;
    if (!safe_strtou64_base(hex_addr.c_str(), &addr, 16)) {
      invalid_addrs++;
      continue;
    }
    char symbol_buf[1024];
    if (google::Symbolize(reinterpret_cast<void*>(addr), symbol_buf, sizeof(symbol_buf))) {
      *output << p << "\t" << symbol_buf << std::endl;
    } else {
      missing_symbols++;
    }
  }

  LOG(INFO) << strings::Substitute(
      "Handled request for /pprof/symbol: requested=$0 invalid_addrs=$1 missing=$2",
      pieces.size(), invalid_addrs, missing_symbols);
}

void AddPprofPathHandlers(Webserver* webserver) {
  // Path handlers for remote pprof profiling. For information see:
  // https://gperftools.googlecode.com/svn/trunk/doc/pprof_remote_servers.html
  webserver->RegisterPathHandler("/pprof/cmdline", "", PprofCmdLineHandler, false, false);
  webserver->RegisterPathHandler("/pprof/heap", "", PprofHeapHandler, false, false);
  webserver->RegisterPathHandler("/pprof/growth", "", PprofGrowthHandler, false, false);
  webserver->RegisterPathHandler("/pprof/profile", "", PprofCpuProfileHandler, false, false);
  webserver->RegisterPathHandler("/pprof/symbol", "", PprofSymbolHandler, false, false);
  webserver->RegisterPathHandler("/pprof/contention", "", PprofContentionHandler, false, false);
}

} // namespace kudu
