// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/zxdb/format/output_buffer.h"

#include <cstdio>
#include <map>
#include <string_view>

#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/format/string_util.h"
#include "src/lib/fxl/strings/split_string.h"

namespace zxdb {

namespace {

// The color codes are taken from the vte 256 colorscheme, which is pretty
// common. If needed, some fallback colors could be established to support
// some old terminal scheme.

// Syntax color codes ----------------------------------------------------------

const char kNormalEscapeCode[] = "\x1b[0m";  // "[0m" = Normal.

using SyntaxColorMap = std::map<Syntax, std::string_view>;
static const SyntaxColorMap& GetSyntaxColorMap() {
  static SyntaxColorMap syntax_color_map = {
      {Syntax::kHeading, "\x1b[1m"},    // "[1m" = Bold.
      {Syntax::kComment, "\x1b[2m"},    // "[2m" = Faint.
      {Syntax::kError, "\x1b[31m"},     // "[31m" = Red.
      {Syntax::kWarning, "\x1b[33m"},   // "[33m" = Yellow.
      {Syntax::kSpecial, "\x1b[34m"},   // "[34m" = Blue.
      {Syntax::kReversed, "\x1b[7m"},   // "[7m" = Reverse video.
      {Syntax::kVariable, "\x1b[36m"},  // "[36m" = Cyan.
      {Syntax::kFileName, "\x1b[95m"},  // "[35m" = Bright Magenta.

      {Syntax::kKeywordBold, "\x1b[1;33m"},   // "[93m" = Bright yellow.
      {Syntax::kKeywordNormal, "\x1b[33m"},   //
      {Syntax::kKeywordDim, "\x1b[2;33m"},    //
      {Syntax::kOperatorBold, "\x1b[1;33m"},  // "[93m" = Bright yellow
      {Syntax::kOperatorNormal, "\x1b[33m"},  //
      {Syntax::kOperatorDim, "\x1b[2;33m"},   //
      {Syntax::kNumberBold, "\x1b[1;95m"},    // "[95m" = Magenta
      {Syntax::kNumberNormal, "\x1b[95m"},    //
      {Syntax::kNumberDim, "\x1b[2;95m"},     //
      {Syntax::kStringBold, "\x1b[1;95m"},    // "[95m" = Magenta
      {Syntax::kStringNormal, "\x1b[95m"},    //
      {Syntax::kStringDim, "\x1b[2;95m"},     //
  };

  return syntax_color_map;
}

// Background color codes ------------------------------------------------------

using BackgroundColorMap = std::map<TextBackgroundColor, std::string_view>;
static const BackgroundColorMap& GetBackgroundColorMap() {
  static BackgroundColorMap background_color_map = {
      {TextBackgroundColor::kBlack, "\x1b[48;5;0m"},
      {TextBackgroundColor::kBlue, "\x1b[48;5;4m"},
      {TextBackgroundColor::kCyan, "\x1b[48;5;6m"},
      {TextBackgroundColor::kGray, "\x1b[48;5;245m"},
      {TextBackgroundColor::kGreen, "\x1b[48;5;2m"},
      {TextBackgroundColor::kMagenta, "\x1b[48;5;5m"},
      {TextBackgroundColor::kRed, "\x1b[48;5;1m"},
      {TextBackgroundColor::kWhite, "\x1b[48;5;15m"},
      {TextBackgroundColor::kYellow, "\x1b[48;5;11m"},

      {TextBackgroundColor::kLightBlue, "\x1b[48;5;45m"},
      {TextBackgroundColor::kLightCyan, "\x1b[48;5;87m"},
      {TextBackgroundColor::kLightGray, "\x1b[48;5;250m"},
      {TextBackgroundColor::kLightGreen, "\x1b[48;5;10m"},
      {TextBackgroundColor::kLightMagenta, "\x1b[48;5;170m"},
      {TextBackgroundColor::kLightRed, "\x1b[48;5;166m"},
      {TextBackgroundColor::kLightYellow, "\x1b[48;5;190m"},
  };

  return background_color_map;
}

// Foreground color codes ------------------------------------------------------

using ForegroundColorMap = std::map<TextForegroundColor, std::string_view>;
static const ForegroundColorMap& GetForegroundColorMap() {
  // We subtract 1 from the sizeof the strings to avoid the end null char.
  static ForegroundColorMap foreground_color_map = {
      {TextForegroundColor::kBlack, "\x1b[38;5;0m"},
      {TextForegroundColor::kBlue, "\x1b[38;5;4m"},
      {TextForegroundColor::kCyan, "\x1b[38;5;6m"},
      {TextForegroundColor::kGray, "\x1b[38;5;245m"},
      {TextForegroundColor::kGreen, "\x1b[38;5;2m"},
      {TextForegroundColor::kMagenta, "\x1b[38;5;5m"},
      {TextForegroundColor::kRed, "\x1b[38;5;1m"},
      {TextForegroundColor::kWhite, "\x1b[38;5;15m"},
      {TextForegroundColor::kYellow, "\x1b[38;5;11m"},

      {TextForegroundColor::kLightBlue, "\x1b[38;5;45m"},
      {TextForegroundColor::kLightCyan, "\x1b[38;5;87m"},
      {TextForegroundColor::kLightGray, "\x1b[38;5;250m"},
      {TextForegroundColor::kLightGreen, "\x1b[38;5;10m"},
      {TextForegroundColor::kLightMagenta, "\x1b[38;5;170m"},
      {TextForegroundColor::kLightRed, "\x1b[38;5;166m"},
      {TextForegroundColor::kLightYellow, "\x1b[38;5;190m"},
  };

  return foreground_color_map;
}

// Writes the given string to stdout.
void FwriteStringView(std::string_view str) { fwrite(str.data(), 1, str.size(), stdout); }

}  // namespace

const char* SyntaxToString(Syntax syntax) {
  switch (syntax) {
    case Syntax::kNormal:
      return "kNormal";
    case Syntax::kComment:
      return "kComment";
    case Syntax::kHeading:
      return "kHeading";
    case Syntax::kError:
      return "kError";
    case Syntax::kWarning:
      return "kWarning";
    case Syntax::kSpecial:
      return "kSpecial";
    case Syntax::kReversed:
      return "kReversed";
    case Syntax::kVariable:
      return "kVariable";
    case Syntax::kFileName:
      return "kFileName";
    case Syntax::kKeywordBold:
      return "kKeywordBold";
    case Syntax::kKeywordNormal:
      return "kKeywordNormal";
    case Syntax::kKeywordDim:
      return "kKeywordDim";
    case Syntax::kOperatorBold:
      return "kOperatorBold";
    case Syntax::kOperatorNormal:
      return "kOperatorNormal";
    case Syntax::kOperatorDim:
      return "kOperatorDim";
    case Syntax::kNumberBold:
      return "kNumberBold";
    case Syntax::kNumberNormal:
      return "kNumberNormal";
    case Syntax::kNumberDim:
      return "kNumberDim";
    case Syntax::kStringBold:
      return "kStringBold";
    case Syntax::kStringNormal:
      return "kStringNormal";
    case Syntax::kStringDim:
      return "kStringDim";
  }
  return nullptr;
}

const char* TextBackgroundColorToString(TextBackgroundColor color) {
  switch (color) {
    case TextBackgroundColor::kDefault:
      return "kDefault";
    case TextBackgroundColor::kBlack:
      return "kBlack";
    case TextBackgroundColor::kBlue:
      return "kBlue";
    case TextBackgroundColor::kCyan:
      return "kCyan";
    case TextBackgroundColor::kGray:
      return "kGray";
    case TextBackgroundColor::kGreen:
      return "kGreen";
    case TextBackgroundColor::kMagenta:
      return "kMagenta";
    case TextBackgroundColor::kRed:
      return "kRed";
    case TextBackgroundColor::kYellow:
      return "kYellow";
    case TextBackgroundColor::kWhite:
      return "kWhite";
    case TextBackgroundColor::kLightBlue:
      return "kLightBlue";
    case TextBackgroundColor::kLightCyan:
      return "kLightCyan";
    case TextBackgroundColor::kLightGray:
      return "kLightGray";
    case TextBackgroundColor::kLightGreen:
      return "kLightGreen";
    case TextBackgroundColor::kLightMagenta:
      return "kLightMagenta";
    case TextBackgroundColor::kLightRed:
      return "kLightRed";
    case TextBackgroundColor::kLightYellow:
      return "kLightYellow";
  }
  return nullptr;
}

const char* TextForegroundColorToString(TextForegroundColor color) {
  switch (color) {
    case TextForegroundColor::kDefault:
      return "kDefault";
    case TextForegroundColor::kBlack:
      return "kBlack";
    case TextForegroundColor::kBlue:
      return "kBlue";
    case TextForegroundColor::kCyan:
      return "kCyan";
    case TextForegroundColor::kGray:
      return "kGray";
    case TextForegroundColor::kGreen:
      return "kGreen";
    case TextForegroundColor::kMagenta:
      return "kMagenta";
    case TextForegroundColor::kRed:
      return "kRed";
    case TextForegroundColor::kYellow:
      return "kYellow";
    case TextForegroundColor::kWhite:
      return "kWhite";
    case TextForegroundColor::kLightBlue:
      return "kLightBlue";
    case TextForegroundColor::kLightCyan:
      return "kLightCyan";
    case TextForegroundColor::kLightGray:
      return "kLightGray";
    case TextForegroundColor::kLightGreen:
      return "kLightGreen";
    case TextForegroundColor::kLightMagenta:
      return "kLightMagenta";
    case TextForegroundColor::kLightRed:
      return "kLightRed";
    case TextForegroundColor::kLightYellow:
      return "kLightYellow";
  }
  return nullptr;
}

OutputBuffer::Span::Span(Syntax s, std::string t) : syntax(s), text(std::move(t)) {}
OutputBuffer::Span::Span(std::string t, TextForegroundColor fg, TextBackgroundColor bg)
    : foreground(fg), background(bg), text(std::move(t)) {}

OutputBuffer::OutputBuffer() = default;

OutputBuffer::OutputBuffer(std::string str, TextForegroundColor fg, TextBackgroundColor bg) {
  spans_.emplace_back(std::move(str), fg, bg);
}

OutputBuffer::OutputBuffer(Syntax syntax, std::string str) {
  spans_.emplace_back(syntax, std::move(str));
}

OutputBuffer::~OutputBuffer() = default;

void OutputBuffer::Append(std::string str, TextForegroundColor fg, TextBackgroundColor bg) {
  spans_.emplace_back(std::move(str), fg, bg);
}

void OutputBuffer::Append(Syntax syntax, std::string str) {
  spans_.emplace_back(syntax, std::move(str));
}

void OutputBuffer::Append(OutputBuffer buf) {
  for (Span& span : buf.spans_)
    spans_.push_back(std::move(span));
}

void OutputBuffer::Append(const Err& err) { spans_.emplace_back(Syntax::kWarning, err.msg()); }

void OutputBuffer::Append(Span span) { spans_.push_back(std::move(span)); }

void OutputBuffer::FormatHelp(const std::string& str) {
  for (auto line : fxl::SplitString(str, "\n", fxl::kKeepWhitespace, fxl::kSplitWantAll)) {
    Syntax syntax;
    if (!line.empty() && line[0] != ' ') {
      // Nonempty lines beginning with non-whitespace are headings.
      syntax = Syntax::kHeading;
    } else {
      syntax = Syntax::kNormal;
    }

    spans_.push_back(Span(syntax, std::string(line)));
    spans_.push_back(Span(Syntax::kNormal, "\n"));
  }
}

void OutputBuffer::WriteToStdout(bool add_newline) const {
  bool ended_in_newline = false;
  for (const Span& span : spans_) {
    // We apply syntax first. If normal, we see if any color are to be set.
    if (span.syntax != Syntax::kNormal) {
      FwriteStringView(GetSyntaxColorMap().at(span.syntax));
    } else {
      if (span.background != TextBackgroundColor::kDefault)
        FwriteStringView(GetBackgroundColorMap().at(span.background));
      if (span.foreground != TextForegroundColor::kDefault)
        FwriteStringView(GetForegroundColorMap().at(span.foreground));
    }

    // The actual raw data to be outputted.
    FwriteStringView(span.text);

    // If any formatting was done, reset the attributes.
    if ((span.syntax != Syntax::kNormal) || (span.background != TextBackgroundColor::kDefault) ||
        (span.foreground != TextForegroundColor::kDefault))
      FwriteStringView(kNormalEscapeCode);

    if (!span.text.empty())
      ended_in_newline = span.text.back() == '\n';
  }

  if (!ended_in_newline && add_newline)
    FwriteStringView("\n");

  std::fflush(stdout);
}

std::string OutputBuffer::AsString() const {
  std::string result;
  for (const Span& span : spans_)
    result.append(span.text);
  return result;
}

size_t OutputBuffer::UnicodeCharWidth() const {
  size_t result = 0;
  for (const Span& span : spans_)
    result += ::zxdb::UnicodeCharWidth(span.text);
  return result;
}

void OutputBuffer::TrimTrailingNewlines() {
  while (!spans_.empty()) {
    std::string& text = spans_.back().text;
    size_t last_good = text.find_last_not_of("\n");
    if (last_good != std::string::npos) {
      text.resize(last_good + 1);
      break;
    }

    spans_.pop_back();
  }
}

void OutputBuffer::Clear() { spans_.clear(); }

std::vector<OutputBuffer::Span> OutputBuffer::NormalizedSpans() const {
  std::vector<Span> normalized;
  for (const auto& cur : spans_) {
    if (normalized.empty()) {
      normalized.push_back(cur);
    } else {
      Span& prev = normalized.back();
      if (prev.syntax == cur.syntax && prev.background == cur.background &&
          prev.foreground == cur.foreground)
        prev.text.append(cur.text);  // Merge: continuation of same format.
      else
        normalized.push_back(cur);  // New format.
    }
  }

  return normalized;
}

std::string OutputBuffer::GetDebugString() const {
  // Normalize so the output is the same even if it was built with different
  // sequences of spans.
  std::vector<Span> normalized = NormalizedSpans();

  std::string result;
  for (size_t i = 0; i < normalized.size(); i++) {
    if (i > 0)
      result += ", ";

    result += SyntaxToString(normalized[i].syntax);
    if (normalized[i].background != TextBackgroundColor::kDefault ||
        normalized[i].foreground != TextForegroundColor::kDefault) {
      result += " ";
      result += TextBackgroundColorToString(normalized[i].background);
      result += " ";
      result += TextForegroundColorToString(normalized[i].foreground);
    }

    result += " \"";
    result += normalized[i].text;
    result.push_back('"');
  }
  return result;
}

bool OutputBuffer::operator==(const OutputBuffer& other) const {
  auto spans = NormalizedSpans();
  auto other_spans = other.NormalizedSpans();

  if (spans.size() != other_spans.size()) {
    return false;
  }

  for (size_t i = 0; i < spans.size(); i++) {
    auto& ours = spans[i];
    auto& theirs = other_spans[i];

    if (ours.syntax != theirs.syntax) {
      return false;
    }

    if (ours.syntax == Syntax::kNormal) {
      if (ours.foreground != theirs.foreground) {
        return false;
      }

      if (ours.background != theirs.background) {
        return false;
      }
    }

    if (ours.text != theirs.text) {
      return false;
    }
  }

  return true;
}

}  // namespace zxdb
