// 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/configuration_constants.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] == kSbFileSepChar) {
        path.erase(idx);
      }
    }
  }
  path.push_back(kSbFileSepChar);
  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
