// 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/default-path-handlers.h"

#include <sstream>
#include <fstream>
#include <sys/stat.h>
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
#include <gutil/strings/substitute.h>

#include "common/logging.h"
#include "rpc/jni-thrift-util.h"
#include "runtime/exec-env.h"
#include "runtime/mem-tracker.h"
#include "service/impala-server.h"
#include "util/cgroup-util.h"
#include "util/common-metrics.h"
#include "util/cpu-info.h"
#include "util/debug-util.h"
#include "util/disk-info.h"
#include "util/jni-util.h"
#include "util/mem-info.h"
#include "util/memusage-path-handlers.h"
#include "util/pprof-path-handlers.h"
#include "util/process-state-info.h"

#include "common/names.h"

using namespace google;
using namespace impala;
using namespace rapidjson;
using namespace strings;

DECLARE_bool(enable_process_lifetime_heap_profiling);
DECLARE_bool(use_local_catalog);
DEFINE_int64(web_log_bytes, 1024 * 1024,
    "The maximum number of bytes to display on the debug webserver's log page");

// Writes the last FLAGS_web_log_bytes of the INFO logfile to a webpage
// Note to get best performance, set GLOG_logbuflevel=-1 to prevent log buffering
void LogsHandler(const Webserver::WebRequest& req, Document* document) {
  string logfile;
  impala::GetFullLogFilename(google::INFO, &logfile);
  Value log_path(logfile.c_str(), document->GetAllocator());
  document->AddMember("logfile", log_path, document->GetAllocator());

  struct stat file_stat;
  if (stat(logfile.c_str(), &file_stat) == 0) {
    long size = file_stat.st_size;
    long seekpos = size < FLAGS_web_log_bytes ? 0L : size - FLAGS_web_log_bytes;
    ifstream log(logfile.c_str(), ios::in);
    // Note if the file rolls between stat and seek, this could fail (and we could wind up
    // reading the whole file). But because the file is likely to be small, this is
    // unlikely to be an issue in practice.
    log.seekg(seekpos);
    document->AddMember("num_bytes", FLAGS_web_log_bytes, document->GetAllocator());
    stringstream ss;
    ss << log.rdbuf();
    Value log_json(ss.str().c_str(), document->GetAllocator());
    document->AddMember("log", log_json, document->GetAllocator());
  } else {
    Value error(Substitute("Couldn't open INFO log file: $0", logfile).c_str(),
        document->GetAllocator());
    document->AddMember("error", error, document->GetAllocator());
  }
}

// Registered to handle "/varz", and produces json containing an array of flag metadata
// objects:
//
// "title": "Command-line Flags",
// "flags": [
//     {
//       "name": "catalog_service_port",
//       "type": "int32",
//       "description": "port where the CatalogService is running",
//       "default": "26000",
//       "current": "26000"
//     },
// .. etc
void FlagsHandler(const Webserver::WebRequest& req, Document* document) {
  vector<CommandLineFlagInfo> flag_info;
  GetAllFlags(&flag_info, true);
  Value flag_arr(kArrayType);
  for (const CommandLineFlagInfo& flag: flag_info) {
    Value flag_val(kObjectType);
    Value name(flag.name.c_str(), document->GetAllocator());
    flag_val.AddMember("name", name, document->GetAllocator());

    Value type(flag.type.c_str(), document->GetAllocator());
    flag_val.AddMember("type", type, document->GetAllocator());

    Value description(flag.description.c_str(), document->GetAllocator());
    flag_val.AddMember("description", description, document->GetAllocator());

    Value default_value(flag.default_value.c_str(), document->GetAllocator());
    flag_val.AddMember("default", default_value, document->GetAllocator());

    Value current_value(flag.current_value.c_str(), document->GetAllocator());
    flag_val.AddMember("current", current_value, document->GetAllocator());

    flag_val.AddMember("experimental", flag.hidden, document->GetAllocator());

    if (!flag.is_default) {
      flag_val.AddMember("value_changed", 1, document->GetAllocator());
    }
    flag_arr.PushBack(flag_val, document->GetAllocator());
  }
  Value title("Command-line Flags", document->GetAllocator());
  document->AddMember("title", title, document->GetAllocator());
  document->AddMember("flags", flag_arr, document->GetAllocator());
}

void JmxHandler(const Webserver::WebRequest& req, Document* document) {
  document->AddMember(rapidjson::StringRef(Webserver::ENABLE_PLAIN_JSON_KEY), true,
      document->GetAllocator());
  TGetJMXJsonResponse result;
  Status status = JniUtil::GetJMXJson(&result);
  if (!status.ok()) {
    Value error(status.GetDetail().c_str(), document->GetAllocator());
    document->AddMember("error", error, document->GetAllocator());
    VLOG(1) << "Error fetching JMX metrics: " << status.GetDetail();
    return;
  }
  // Parse the JSON string returned from fe. We do an additional round of
  // parsing to populate the JSON structure in the 'document' for our template
  // rendering to work correctly. Otherwise the whole JSON content is considered
  // as a single string mapped to another key.
  Document doc(&document->GetAllocator());
  doc.Parse<kParseDefaultFlags>(result.jmx_json.c_str());
  if (doc.HasParseError()) {
    Value error(GetParseError_En(doc.GetParseError()), document->GetAllocator());
    document->AddMember("error", error, document->GetAllocator());
    VLOG(1) << "Error fetching JMX metrics: " << doc.GetParseError();
    return;
  }
  // Populate the members in the document. Due to MOVE semantic of RapidJSON,
  // the ownership will be transferred to the target document.
  for (Value::MemberIterator it = doc.MemberBegin(); it != doc.MemberEnd(); ++it) {
    document->AddMember(it->name, it->value, document->GetAllocator());
  }
}

// Helper function that creates a Value for a given build flag name, value and adds it to
// an array of build_flags
void AddBuildFlag(const std::string& flag_name, const std::string& flag_value,
    Document* document, Value* build_flags) {
  Value build_type(kObjectType);
  Value build_type_name(flag_name.c_str(), document->GetAllocator());
  build_type.AddMember("flag_name", build_type_name, document->GetAllocator());
  Value build_type_value(flag_value.c_str(), document->GetAllocator());
  build_type.AddMember("flag_value", build_type_value, document->GetAllocator());
  build_flags->PushBack(build_type, document->GetAllocator());
}

namespace impala {

void RootHandler(const Webserver::WebRequest& req, Document* document) {
  Value version(GetVersionString().c_str(), document->GetAllocator());
  document->AddMember("version", version, document->GetAllocator());

#ifdef NDEBUG
  const char* is_ndebug = "true";
#else
  const char* is_ndebug = "false";
#endif

  Value build_flags(kArrayType);
  AddBuildFlag("is_ndebug", is_ndebug, document, &build_flags);
  string cmake_build_type(GetCMakeBuildType());
  replace(cmake_build_type.begin(), cmake_build_type.end(), '-', '_');
  AddBuildFlag("cmake_build_type", cmake_build_type, document, &build_flags);
  AddBuildFlag("library_link_type", GetLibraryLinkType(), document, &build_flags);
  document->AddMember("build_flags", build_flags, document->GetAllocator());

  Value cpu_info(CpuInfo::DebugString().c_str(), document->GetAllocator());
  document->AddMember("cpu_info", cpu_info, document->GetAllocator());
  Value mem_info(MemInfo::DebugString().c_str(), document->GetAllocator());
  document->AddMember("mem_info", mem_info, document->GetAllocator());
  Value disk_info(DiskInfo::DebugString().c_str(), document->GetAllocator());
  document->AddMember("disk_info", disk_info, document->GetAllocator());
  Value os_info(OsInfo::DebugString().c_str(), document->GetAllocator());
  document->AddMember("os_info", os_info, document->GetAllocator());
  Value process_state_info(
      ProcessStateInfo().DebugString().c_str(), document->GetAllocator());
  document->AddMember("process_state_info", process_state_info, document->GetAllocator());
  Value cgroup_info(CGroupUtil::DebugString().c_str(), document->GetAllocator());
  document->AddMember("cgroup_info", cgroup_info, document->GetAllocator());

  if (CommonMetrics::PROCESS_START_TIME != nullptr) {
    Value process_start_time(
        CommonMetrics::PROCESS_START_TIME->GetValue().c_str(), document->GetAllocator());
    document->AddMember(
        "process_start_time", process_start_time, document->GetAllocator());
  }

  ExecEnv* env = ExecEnv::GetInstance();
  if (env == nullptr || env->impala_server() == nullptr) return;
  ImpalaServer* impala_server = env->impala_server();
  document->AddMember("impala_server_mode", true, document->GetAllocator());
  document->AddMember("is_coordinator", impala_server->IsCoordinator(),
      document->GetAllocator());
  document->AddMember("use_local_catalog", FLAGS_use_local_catalog,
      document->GetAllocator());
  document->AddMember("is_executor", impala_server->IsExecutor(),
      document->GetAllocator());
  bool is_quiescing = impala_server->IsShuttingDown();
  document->AddMember("is_quiescing", is_quiescing, document->GetAllocator());
  if (is_quiescing) {
    Value shutdown_status(
        impala_server->ShutdownStatusToString(impala_server->GetShutdownStatus()).c_str(),
        document->GetAllocator());
    document->AddMember("shutdown_status", shutdown_status, document->GetAllocator());
  }
}

void AddDefaultUrlCallbacks(Webserver* webserver, MetricGroup* metric_group,
    MemTracker* process_mem_tracker) {
  webserver->RegisterUrlCallback("/logs", "logs.tmpl", LogsHandler, true);
  webserver->RegisterUrlCallback("/varz", "flags.tmpl", FlagsHandler, true);
  if (JniUtil::is_jvm_inited()) {
    // JmxHandler outputs a plain JSON string and does not require a template to
    // render. However RawUrlCallback only supports PLAIN content type.
    // (TODO): Switch to RawUrlCallback when it supports JSON content-type.
    webserver->RegisterUrlCallback("/jmx", "raw_text.tmpl", JmxHandler, true);
  }
  AddMemUsageCallbacks(webserver, process_mem_tracker, metric_group);

#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
  // Remote (on-demand) profiling is disabled if the process is already being profiled.
  if (!FLAGS_enable_process_lifetime_heap_profiling) {
    AddPprofUrlCallbacks(webserver);
  }
#endif

  auto root_handler =
    [](const Webserver::WebRequest& req, Document* doc) {
      RootHandler(req, doc);
    };
  webserver->RegisterUrlCallback("/", "root.tmpl", root_handler, true);
}

}
