// Copyright 2016 The Cobalt 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 "cobalt/browser/memory_tracker/tool.h"

#include <cstdlib>
#include <map>
#include <memory>
#include <string>

#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "cobalt/browser/memory_tracker/tool/compressed_time_series_tool.h"
#include "cobalt/browser/memory_tracker/tool/internal_fragmentation_tool.h"
#include "cobalt/browser/memory_tracker/tool/leak_finder_tool.h"
#include "cobalt/browser/memory_tracker/tool/log_writer_tool.h"
#include "cobalt/browser/memory_tracker/tool/malloc_logger_tool.h"
#include "cobalt/browser/memory_tracker/tool/malloc_stats_tool.h"
#include "cobalt/browser/memory_tracker/tool/memory_size_binner_tool.h"
#include "cobalt/browser/memory_tracker/tool/print_csv_tool.h"
#include "cobalt/browser/memory_tracker/tool/print_tool.h"
#include "cobalt/browser/memory_tracker/tool/tool_impl.h"
#include "cobalt/browser/memory_tracker/tool/tool_thread.h"
#include "nb/analytics/memory_tracker_helpers.h"
#include "starboard/common/log.h"
#include "starboard/configuration.h"
#include "starboard/double.h"
#include "starboard/file.h"

namespace cobalt {
namespace browser {
namespace memory_tracker {

#if !defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
// Null implementation for memory tracker tool.
class NullTool : public Tool {
 public:
  virtual ~NullTool() {}
};

// Instantiates the memory tracker tool from the command argument.
std::unique_ptr<Tool> CreateMemoryTrackerTool(const std::string&) {
  return std::unique_ptr<Tool>(new NullTool);
}

#else

using nb::analytics::MemoryTracker;

namespace {
enum SwitchEnum {
  kNull,
  kStartup,
  kContinuousPrinter,
  kCompressedTimeseries,
  kBinnerAnalytics,
  kAllocationLogger,
  kLeakTracer,
  kJavascriptLeakTracer,
  kInternalFragmentationTracer,
  kMallocStats,
  kMallocLogger,
};

struct SwitchVal {
  SwitchVal() : help_msg(), enum_value(kNull) {}
  SwitchVal(const SwitchVal& other)
      : tool_name(other.tool_name),
        help_msg(other.help_msg),
        enum_value(other.enum_value) {}
  SwitchVal(const char* name, const char* msg, SwitchEnum val)
      : tool_name(name), help_msg(msg), enum_value(val) {}

  std::string tool_name;
  std::string help_msg;
  SwitchEnum enum_value;
};

class SbLogger : public AbstractLogger {
 public:
  void Output(const char* str) override { LOG(INFO) << str; }
  void Flush() override { SbLogFlush(); }
};

class FileLogger : public AbstractLogger {
 public:
  explicit FileLogger(const std::string& filename);
  ~FileLogger();
  void Output(const char* str) override {
    if (SbFileIsValid(log_file_)) {
      SbFileWrite(log_file_, str, static_cast<int>(strlen(str)));
      SbFileFlush(log_file_);
    } else {
      LOG(INFO) << str;
    }
  }
  void Flush() override { SbLogFlush(); }

 private:
  SbFile log_file_;
};

FileLogger::FileLogger(const std::string& filename)
    : log_file_(kSbFileInvalid) {
  char file_name_buff[2048] = {};
  SbSystemGetPath(kSbSystemPathDebugOutputDirectory, file_name_buff,
                  arraysize(file_name_buff));
  std::string path(file_name_buff);
  if (!path.empty()) {  // Protect against a dangling "/" at end.
    const int back_idx_signed = static_cast<int>(path.length()) - 1;
    if (back_idx_signed >= 0) {
      const size_t idx = back_idx_signed;
      if (path[idx] == SB_FILE_SEP_CHAR) {
        path.erase(idx);
      }
    }
  }
  path.push_back(SB_FILE_SEP_CHAR);
  path.append(filename);
  int flags = kSbFileCreateAlways | kSbFileWrite;
  bool created_ok = false;
  SbFileError error_code = kSbFileOk;
  log_file_ = SbFileOpen(path.c_str(), flags, &created_ok, &error_code);
  if (log_file_ == kSbFileInvalid || !created_ok) {
    LOG(ERROR) << "Error creating log file";
    return;
  } else {
    LOG(INFO) << "Logging to file: " << path;
  }
}

FileLogger::~FileLogger() {
  SbFileClose(log_file_);
  log_file_ = kSbFileInvalid;
}  // namespace

// Parses out the toolname for a tool command.
// Example:
//   INPUT:  "tool_name(arg):filename"
//   OUTPUT: "tool_name"
std::string ParseToolName(const std::string& command_arg) {
  const size_t first_open_paren_idx = command_arg.find('(');
  if (first_open_paren_idx == std::string::npos) {
    const size_t first_colon_idx = command_arg.find(':');
    if (first_colon_idx == std::string::npos) {
      return command_arg;
    }
    return command_arg.substr(0, first_colon_idx);
  }
  return command_arg.substr(0, first_open_paren_idx);
}

// Parses out the output filename for a tool command.
// Example:
//   INPUT:  "tool_name(arg):filename"
//   OUTPUT: "filename"
std::string ParseFileName(const std::string& command_arg) {
  const size_t first_colon_idx = command_arg.find(':');
  if (first_colon_idx == std::string::npos) {
    return "";
  }
  return command_arg.substr(1 + first_colon_idx);
}

// Parses out the arguments for a tool.
// Example:
//   INPUT:  "tool_name(arg):filename"
//   OUTPUT: "arg"
std::string ParseToolArg(const std::string& command_arg) {
  const size_t first_open_paren_idx = command_arg.find('(');
  const size_t last_closing_paren_idx = command_arg.find_last_of(')');

  if ((first_open_paren_idx == std::string::npos) ||
      (last_closing_paren_idx == std::string::npos)) {
    return "";
  }

  if (last_closing_paren_idx < first_open_paren_idx) {
    return "";
  }

  const size_t begin_idx = first_open_paren_idx + 1;
  const size_t length = (last_closing_paren_idx - begin_idx);
  std::string arg_str = command_arg.substr(begin_idx, length);
  return arg_str;
}

struct DisableMemoryTrackerInScope {
  explicit DisableMemoryTrackerInScope(MemoryTracker* tracker)
      : tracker_(tracker) {
    if (tracker_) {
      tracker_->SetMemoryTrackingEnabled(false);
    }
  }

  ~DisableMemoryTrackerInScope() {
    if (tracker_) {
      tracker_->SetMemoryTrackingEnabled(true);
    }
  }

  MemoryTracker* tracker_;
};

}  // namespace.

class MemoryTrackerThreadImpl : public Tool {
 public:
  explicit MemoryTrackerThreadImpl(base::SimpleThread* ptr)
      : thread_ptr_(ptr) {}
  ~MemoryTrackerThreadImpl() override { thread_ptr_.reset(NULL); }
  std::unique_ptr<base::SimpleThread> thread_ptr_;
};

std::unique_ptr<Tool> CreateMemoryTrackerTool(const std::string& command_arg) {
  // The command line switch for memory_tracker was used. Look into the args
  // and determine the mode that the memory_tracker should be used for.

  // The map is used to
  // 1) Resolve the string to an enum.
  // 2) Print a useful help method of all known memory_tracker modes.
  typedef std::map<std::string, SwitchVal> SwitchMap;

  SwitchVal startup_tool(
      "startup(num_mins=1)",  // Name of tool.
      "  Records high-frequency memory metrics for the first 60\n"
      "  seconds of program launch and then dumps it out in CSV format\n"
      "  to stdout.\n",
      kStartup);

  SwitchVal continuous_printer_tool(
      "continuous_printer",  // Name of tool.
      "  Once every second the memory state is dumped to stdout.\n",
      kContinuousPrinter);

  SwitchVal compressed_timeseries_tool(
      "compressed_timeseries",  // Name of tool.
      "  Use this tool to see the growth in memory usage as the app runs.\n"
      "  The memory growth is segmented into memory scopes and outputted as\n"
      "  CSV. The compressed time-series will depict the full history of\n"
      "  the memory using a fixed number of rows. Older history has degraded\n"
      "  resolution and while new entries are captured in full detail. This\n"
      "  achieved by evicting old entries by an exponential decay scheme.\n",
      kCompressedTimeseries);

  SwitchVal binner_tool(
      "binner(region=NULL)",
      "  Dumps memory statistics once a second in CSV format to stdout.\n"
      "  The default memory region is all memory regions. Pass the\n"
      "  name of the memory region to specify that only that memory region\n"
      "  should be tracked. For example: binner(Javascript).\n",
      kBinnerAnalytics);

  SwitchVal allocation_logger_tool(
      "allocation_logger",
      "  Continuously writes allocations and deallocations to\n"
      "  memory_log.txt. This is a legacy format used by lbshell. The\n"
      "  location of this memory_log.txt file is in the platform dependent\n"
      "  directory specified by kSbSystemPathDebugOutputDirectory.\n",
      kAllocationLogger);

  SwitchVal leak_tracing_tool(
      "leak_tracer",
      "  Automatically detects leaks and reports them in CSV format.\n",
      kLeakTracer);

  SwitchVal js_leak_tracing_tool(
      "js_leak_tracer",
      "  Automatically detects Javascript leaks and reports them in CSV\n"
      "  format.\n",
      kJavascriptLeakTracer);

  SwitchVal internal_fragmentation_tracer_tool(
      "internal_fragmentation_tracer",
      "  Traces internal fragmentation and stores it in CSV format.\n",
      kInternalFragmentationTracer);

  SwitchVal malloc_stats_tool(
      "malloc_stats",
      "  Queries the allocation system for memory usage. This is the most\n"
      "  lightweight tool. Output is CSV format.\n",
      kMallocStats);

  SwitchVal malloc_logger_tool(
      "malloc_logger",
      "  Continuously writes allocations, deallocations, allocation location\n"
      "  and malloc stats to memory_log_<timestamp>.csv, without headers.\n"
      "  The location of this log file is in the platform dependent\n"
      "  directory specified by kSbSystemPathDebugOutputDirectory.\n",
      kMallocLogger);

  SwitchMap switch_map;
  switch_map[ParseToolName(startup_tool.tool_name)] = startup_tool;
  switch_map[ParseToolName(continuous_printer_tool.tool_name)] =
      continuous_printer_tool;
  switch_map[ParseToolName(compressed_timeseries_tool.tool_name)] =
      compressed_timeseries_tool;
  switch_map[ParseToolName(binner_tool.tool_name)] = binner_tool;
  switch_map[ParseToolName(allocation_logger_tool.tool_name)] =
      allocation_logger_tool;
  switch_map[ParseToolName(leak_tracing_tool.tool_name)] = leak_tracing_tool;
  switch_map[ParseToolName(js_leak_tracing_tool.tool_name)] =
      js_leak_tracing_tool;
  switch_map[ParseToolName(internal_fragmentation_tracer_tool.tool_name)] =
      internal_fragmentation_tracer_tool;
  switch_map[ParseToolName(malloc_logger_tool.tool_name)] = malloc_logger_tool;

  switch_map[ParseToolName(malloc_stats_tool.tool_name)] = malloc_stats_tool;

  std::string tool_name = ParseToolName(command_arg);
  std::string tool_arg = ParseToolArg(command_arg);
  std::string filename = ParseFileName(command_arg);

  // FAST OUT - is a thread type not selected? Then print out a help menu
  // and request that the app should shut down.
  SwitchMap::const_iterator found_it = switch_map.find(tool_name);
  if (found_it == switch_map.end()) {
    // Error, tell the user what to do instead and then exit.
    std::stringstream ss;
    ss << "\nNo memory tracker tool selected so help has been invoked:\n";
    ss << "Memory Tracker help:\n";
    for (SwitchMap::const_iterator it = switch_map.begin();
         it != switch_map.end(); ++it) {
      const std::string& name = it->first;
      const SwitchVal& val = it->second;
      ss << "    memory_tracker=" << name << " \n" << val.help_msg;
    }
    ss << "\nIf the string has a colon, then the name after the colon is used\n"
          "as the filename for output.\n"
          "For example: \"leak_tracer:leaks.csv\"\n";
    LOG(INFO) << ss.str();
    ss.str("");  // Clears the contents of stringstream.

    // Try and turn off all logging so that the stdout is less likely to be
    // polluted by interleaving output.
    logging::SetMinLogLevel(INT_MAX);
    // SbThreadSleep wants microseconds. We sleep here so that the user can
    // read the help message before the engine starts up again and the
    // fills the output with more logging text.
    const SbTime four_seconds = 4000 * kSbTimeMillisecond;
    SbThreadSleep(four_seconds);

    found_it = switch_map.find(continuous_printer_tool.tool_name);

    // One more help message and 1-second pause. Then continue on with the
    // execution as normal.
    const SbTime one_second = 1000 * kSbTimeMillisecond;
    SbThreadSleep(one_second);
  }

  // Okay we have been resolved to use a memory tracker in some way.
  DLOG(INFO) << "\n\nUsing MemoryTracking=" << found_it->first << "\n";

  // Tools are expected to instantiate the MemoryTracker if they need it.
  MemoryTracker* memory_tracker = NULL;
  std::unique_ptr<AbstractTool> tool_ptr;

  const SwitchVal& value = found_it->second;
  switch (value.enum_value) {
    case kNull: {
      SB_NOTREACHED();
      break;
    }
    case kStartup: {
      double num_mins = 1.0;
      if (!tool_arg.empty()) {
        if (!base::StringToDouble(tool_arg, &num_mins) ||
            SbDoubleIsNan(num_mins) || num_mins <= 0) {
          num_mins = 1.0;
        }
      }
      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();

      // Converts minutes into Sampling interval and also total sampling time.
      // To keep the amount of elements in the output static, we adjust the
      // sampling.
      //
      // The number of samples produced is held constants and is:
      //   kNumSamples = F::TotalSamplingTime(num_mins) /
      //                 F::SamplingIntervalMs(num_mins)
      struct F {
        static int SamplingIntervalMs(double mins) {
          // kNumSamples is chosen such that SamplingIntervalMs(1) outputs
          // 240ms.
          static const double kNumSamples = 250.;
          const int sample_time_ms =
              static_cast<int>(ToMilliseconds(mins) / kNumSamples);
          return static_cast<int>(sample_time_ms);
        }

        // TotalSamplingTime(1) outputs 60,000 milliseconds, or 1 minute.
        static int ToMilliseconds(double mins) {
          const double millseconds = mins * 60. * 1000.;
          return static_cast<int>(millseconds);
        }
      };

      // Sample time increases with the number of seconds. At one second we
      // sample 4 times a second. This keeps the number of samples constant
      // regardless of input time.
      int sampling_interval_ms = F::SamplingIntervalMs(num_mins);
      // Time until output is triggered.
      int sampling_time_ms = F::ToMilliseconds(num_mins);
      // Create a thread that will gather memory metrics for startup.
      DisableMemoryTrackerInScope disable_in_scope(memory_tracker);
      tool_ptr.reset(new PrintCSVTool(sampling_interval_ms, sampling_time_ms));
      break;
    }
    case kContinuousPrinter: {
      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      // Create a thread that will continuously report memory use.
      DisableMemoryTrackerInScope disable_in_scope(memory_tracker);
      tool_ptr.reset(new PrintTool);
      break;
    }
    case kCompressedTimeseries: {
      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      // Create a thread that will continuously report memory use.
      DisableMemoryTrackerInScope disable_in_scope(memory_tracker);
      tool_ptr.reset(new CompressedTimeSeriesTool);
      break;
    }
    case kBinnerAnalytics: {
      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      DisableMemoryTrackerInScope disable_in_scope(memory_tracker);
      // Create a thread that will continuously report javascript memory
      // analytics.
      tool_ptr.reset(new MemorySizeBinnerTool(tool_arg));
      break;
    }
    case kAllocationLogger: {
      std::unique_ptr<LogWriterTool> disk_writer_tool(new LogWriterTool());
      tool_ptr.reset(disk_writer_tool.release());
      break;
    }
    case kLeakTracer: {
      std::unique_ptr<LeakFinderTool> leak_finder(
          new LeakFinderTool(LeakFinderTool::kCPlusPlus));

      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      memory_tracker->SetMemoryTrackerDebugCallback(leak_finder.get());
      tool_ptr.reset(leak_finder.release());
      break;
    }
    case kJavascriptLeakTracer: {
      std::unique_ptr<LeakFinderTool> leak_finder(
          new LeakFinderTool(LeakFinderTool::kJavascript));

      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      memory_tracker->SetMemoryTrackerDebugCallback(leak_finder.get());
      tool_ptr.reset(leak_finder.release());
      break;
    }
    case kInternalFragmentationTracer: {
      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      tool_ptr.reset(new InternalFragmentationTool());
      break;
    }
    case kMallocStats: {
      tool_ptr.reset(new MallocStatsTool);
      break;
    }
    case kMallocLogger: {
      std::unique_ptr<MallocLoggerTool> malloc_logger(new MallocLoggerTool());

      memory_tracker = MemoryTracker::Get();
      memory_tracker->InstallGlobalTrackingHooks();
      memory_tracker->SetMemoryTrackerDebugCallback(malloc_logger.get());
      tool_ptr.reset(malloc_logger.release());
      break;
    }
  }

  if (tool_ptr.get()) {
    DisableMemoryTrackerInScope disable_in_scope(memory_tracker);
    AbstractLogger* logger = NULL;
    if (!filename.empty()) {
      logger = new FileLogger(filename);
    }
    if (!logger) {
      logger = new SbLogger;
    }
    base::SimpleThread* thread = new ToolThread(memory_tracker,  // May be NULL.
                                                tool_ptr.release(), logger);
    return std::unique_ptr<Tool>(new MemoryTrackerThreadImpl(thread));
  } else {
    return std::unique_ptr<Tool>();
  }
}

#endif  // !defined(STARBOARD_ALLOWS_MEMORY_TRACKING)

}  // namespace memory_tracker
}  // namespace browser
}  // namespace cobalt
