// 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/console/output_buffer.h"

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

#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/console/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_.push_back(Span(Syntax::kNormal, 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() 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)
    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
