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

#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/developer/debug/zxdb/console/string_util.h"
#include "src/lib/fxl/logging.h"

namespace zxdb {

namespace {

template <typename CellType>
bool SpansRemainingCols(const std::vector<ColSpec>& spec,
                        const std::vector<CellType>& row, size_t column) {
  // The last item in a row will span all remaining columns if there are more
  // in the column spec.
  return column == row.size() - 1 && column < spec.size() - 1;
}

// Character width for both cell types.
int CellWidth(const std::string& str) {
  return static_cast<int>(UnicodeCharWidth(str));
}
int CellWidth(const OutputBuffer& buf) {
  return static_cast<int>(buf.UnicodeCharWidth());
}

// Appends the given cell type to the OutputBuffer. The Syntax is ignored
// in the OutputBuffer->OutputBuffer variant because it will contain its own
// syntax.
void AppendCell(const std::string& str, Syntax syntax, OutputBuffer* out) {
  out->Append(syntax, str);
}
void AppendCell(const OutputBuffer& buf, Syntax, OutputBuffer* out) {
  out->Append(buf);
}

// Appends the given string to the output, padding with spaces to the width
// as necessary.
template <typename CellType>
void AppendPadded(const CellType& cell, int width, Align align, Syntax syntax,
                  bool is_last_col, OutputBuffer* out) {
  int pad = std::max(0, width - CellWidth(cell));
  if (pad > 0 && align == Align::kRight)
    out->Append(std::string(pad, ' '));

  AppendCell(cell, syntax, out);

  // Padding on the right. Don't add for the last col.
  if (pad > 0 && !is_last_col && align == Align::kLeft)
    out->Append(std::string(pad, ' '));

  // Separator after columns for all but the last.
  if (!is_last_col)
    out->Append(std::string(1, ' '));
}

// Backend for FormatColumns variants. The requirements are that CellWidth()
// and AppendCell() are define for CellType.
template <typename CellType>
void FormatTableT(const std::vector<ColSpec>& spec,
                  const std::vector<std::vector<CellType>>& rows,
                  OutputBuffer* out) {
  std::vector<int> max;  // Max width of each column.

  // Max widths of headings.
  bool has_head = false;
  for (const auto& col : spec) {
    max.push_back(UnicodeCharWidth(col.head));
    has_head |= !col.head.empty();
  }

  // Max widths of contents.
  for (const auto& row : rows) {
    FXL_DCHECK(row.size() <= max.size()) << "Column spec size is too small.";
    for (size_t i = 0; i < row.size(); i++) {
      // Only count the ones that don't overflow (either because they span the
      // remaining columns, or because they're beyond max_width).
      if (!SpansRemainingCols(spec, row, i)) {
        int cell_size = CellWidth(row[i]);
        if (spec[i].max_width == 0 || cell_size <= spec[i].max_width)
          max[i] = std::max(max[i], cell_size);
      }
    }
  }

  // Print heading.
  if (has_head) {
    for (size_t i = 0; i < max.size(); i++) {
      const ColSpec& col = spec[i];
      if (col.pad_left)
        out->Append(Syntax::kNormal, std::string(col.pad_left, ' '));
      AppendPadded(col.head, max[i], col.align, Syntax::kHeading,
                   i == max.size() - 1, out);
    }
    out->Append("\n");
  }

  // Print rows.
  for (const auto& row : rows) {
    std::string text;
    for (size_t i = 0; i < row.size(); i++) {
      const ColSpec& col = spec[i];
      if (SpansRemainingCols(spec, row, i)) {
        AppendCell(row[i], col.syntax, out);
      } else {
        if (col.pad_left)
          out->Append(Syntax::kNormal, std::string(col.pad_left, ' '));
        AppendPadded(row[i], max[i], col.align, col.syntax, i == max.size() - 1,
                     out);
      }
    }
    out->Append("\n");
  }
}

}  // namespace

void FormatTable(const std::vector<ColSpec>& spec,
                 const std::vector<std::vector<std::string>>& rows,
                 OutputBuffer* out) {
  FormatTableT<std::string>(spec, rows, out);
}

void FormatTable(const std::vector<ColSpec>& spec,
                 const std::vector<std::vector<OutputBuffer>>& rows,
                 OutputBuffer* out) {
  FormatTableT<OutputBuffer>(spec, rows, out);
}

}  // namespace zxdb
