/*
 * Copyright 2017 Google Inc. 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_settings/pretty_print.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/string_split.h"
#include "cobalt/browser/memory_settings/memory_settings.h"
#include "cobalt/browser/memory_settings/table_printer.h"
#include "starboard/log.h"
#include "starboard/string.h"

namespace cobalt {
namespace browser {
namespace memory_settings {
namespace {

std::string StringifyMemoryType(const MemorySetting& setting) {
  switch (setting.memory_type()) {
    case MemorySetting::kCPU: {
      return "CPU";
    }
    case MemorySetting::kGPU: {
      return "GPU";
    }
    case MemorySetting::kNotApplicable: {
      return "N/A";
    }
  }

  SB_NOTIMPLEMENTED() << "Unimplemented string for memory type: "
                      << setting.memory_type();
  return "UNKNOWN";
}

std::string StringifyValue(const MemorySetting* setting) {
  if (!setting->valid()) {
    return "N/A";
  }
  return setting->ValueToString();
}

void FillStream(size_t count, const char fill_ch, std::stringstream* ss) {
  for (size_t i = 0; i < count; ++i) {
    (*ss) << fill_ch;
  }
}

}  // namespace

std::string GeneratePrettyPrintTable(
    bool use_color_ascii,
    const std::vector<const MemorySetting*>& settings) {
  TablePrinter printer;
  if (use_color_ascii) {
    printer.set_text_color(TablePrinter::kGreen);
  }
  std::vector<std::string> header;
  header.push_back("SETTING NAME");
  header.push_back("VALUE");
  header.push_back("");
  header.push_back("TYPE");
  header.push_back("SOURCE");
  printer.AddRow(header);

  for (size_t i = 0; i < settings.size(); ++i) {
    const MemorySetting* setting = settings[i];

    std::vector<std::string> row;
    row.push_back(setting->name());
    row.push_back(StringifyValue(setting));
    if (setting->valid()) {
      row.push_back(ToMegabyteString(setting->MemoryConsumption(), 1));
    } else {
      row.push_back("N/A");
    }
    row.push_back(StringifyMemoryType(*setting));
    row.push_back(StringifySourceType(*setting));
    printer.AddRow(row);
  }

  std::string table_string = printer.ToString();
  return table_string;
}

std::string GenerateMemoryTable(bool use_color_ascii,
                                const IntSetting& total_cpu_memory,
                                const IntSetting& total_gpu_memory,
                                int64_t settings_cpu_consumption,
                                int64_t settings_gpu_consumption) {
  TablePrinter printer;
  if (use_color_ascii) {
    printer.set_text_color(TablePrinter::kGreen);
  }
  std::vector<std::string> header;
  header.push_back("MEMORY");
  header.push_back("SOURCE");
  header.push_back("TOTAL");
  header.push_back("SETTINGS CONSUME");
  printer.AddRow(header);

  std::vector<std::string> data_row;
  data_row.push_back(total_cpu_memory.name());
  data_row.push_back(StringifySourceType(total_cpu_memory));
  data_row.push_back(ToMegabyteString(total_cpu_memory.value(), 1));
  data_row.push_back(ToMegabyteString(settings_cpu_consumption, 1));
  printer.AddRow(data_row);
  data_row.clear();

  data_row.push_back(total_gpu_memory.name());
  data_row.push_back(StringifySourceType(total_gpu_memory));
  std::string total_gpu_consumption_str;

  const bool available_gpu_settings_invalid = (total_gpu_memory.value() <= 0);

  if (available_gpu_settings_invalid) {
    total_gpu_consumption_str = "<UNKNOWN>";
  } else {
    total_gpu_consumption_str = ToMegabyteString(total_gpu_memory.value(), 1);
  }

  data_row.push_back(total_gpu_consumption_str);
  data_row.push_back(ToMegabyteString(settings_gpu_consumption, 1));
  printer.AddRow(data_row);
  data_row.clear();
  return printer.ToString();
}

std::string ToMegabyteString(int64_t bytes, int decimal_places) {
  float megabytes = bytes / (1024.0f * 1024.0f);

  std::stringstream ss_fmt;
  // e.g. "%.1f MB"
  ss_fmt << "%." << decimal_places << "f MB";

  char buff[128];
  SbStringFormatF(buff, sizeof(buff), ss_fmt.str().c_str(), megabytes);
  // Use 16
  return std::string(buff);
}

std::string MakeBorder(const std::string& body, const char border_ch) {
  std::vector<std::string> lines;
  base::SplitStringDontTrim(body, '\n', &lines);

  size_t max_span = 0;
  for (size_t i = 0; i < lines.size(); ++i) {
    max_span = std::max(max_span, lines[i].size());
  }

  std::stringstream ss;
  ss << "\n\n";

  FillStream(max_span + 4, border_ch, &ss);
  ss << "\n";
  for (size_t i = 0; i < lines.size(); ++i) {
    const std::string& line = lines[i];

    ss << border_ch << ' ' << line;
    FillStream(max_span - line.size() + 1, ' ', &ss);
    ss << border_ch;
    ss << "\n";
  }
  FillStream(max_span + 4, border_ch, &ss);
  ss << "\n\n";
  return ss.str();
}

std::string StringifySourceType(const MemorySetting& setting) {
  if (!setting.valid()) {
    return "N/A";
  }

  switch (setting.source_type()) {
    case MemorySetting::kUnset: {
      return "Unset";
    }
    case MemorySetting::kStarboardAPI: {
      return "Starboard API";
    }
    case MemorySetting::kBuildSetting: {
      return "Build";
    }
    case MemorySetting::kCmdLine: {
      return "CmdLine";
    }
    case MemorySetting::kAutoSet: {
      return "AutoSet";
    }
    case MemorySetting::kAutosetConstrained: {
      return "AutoSet (Constrained)";
    }
  }

  SB_NOTIMPLEMENTED() << "Unimplemented string for type: "
                      << setting.source_type();
  return "UNKNOWN";
}

}  // namespace memory_settings
}  // namespace browser
}  // namespace cobalt
