// Copyright (c) 2013 The Chromium 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 "tools/gn/err.h"

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/input_file.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/standard_out.h"
#include "tools/gn/tokenizer.h"
#include "tools/gn/value.h"

namespace {

std::string GetNthLine(const base::StringPiece& data, int n) {
  size_t line_off = Tokenizer::ByteOffsetOfNthLine(data, n);
  size_t end = line_off + 1;
  while (end < data.size() && !Tokenizer::IsNewline(data, end))
    end++;
  return data.substr(line_off, end - line_off).as_string();
}

void FillRangeOnLine(const LocationRange& range, int line_number,
                     std::string* line) {
  // Only bother if the range's begin or end overlaps the line. If the entire
  // line is highlighted as a result of this range, it's not very helpful.
  if (range.begin().line_number() != line_number &&
      range.end().line_number() != line_number)
    return;

  // Watch out, the char offsets in the location are 1-based, so we have to
  // subtract 1.
  int begin_char;
  if (range.begin().line_number() < line_number)
    begin_char = 0;
  else
    begin_char = range.begin().char_offset() - 1;

  int end_char;
  if (range.end().line_number() > line_number)
    end_char = line->size();  // Ending is non-inclusive.
  else
    end_char = range.end().char_offset() - 1;

  CHECK(end_char >= begin_char);
  CHECK(begin_char >= 0 && begin_char <= static_cast<int>(line->size()));
  CHECK(end_char >= 0 && end_char <= static_cast<int>(line->size()));
  for (int i = begin_char; i < end_char; i++)
    line->at(i) = '-';
}

// The line length is used to clip the maximum length of the markers we'll
// make if the error spans more than one line (like unterminated literals).
void OutputHighlighedPosition(const Location& location,
                              const Err::RangeList& ranges,
                              size_t line_length) {
  // Make a buffer of the line in spaces.
  std::string highlight;
  highlight.resize(line_length);
  for (size_t i = 0; i < line_length; i++)
    highlight[i] = ' ';

  // Highlight all the ranges on the line.
  for (size_t i = 0; i < ranges.size(); i++)
    FillRangeOnLine(ranges[i], location.line_number(), &highlight);

  // Allow the marker to be one past the end of the line for marking the end.
  highlight.push_back(' ');
  CHECK(location.char_offset() - 1 >= 0 &&
        location.char_offset() - 1 < static_cast<int>(highlight.size()));
  highlight[location.char_offset() - 1] = '^';

  // Trim unused spaces from end of line.
  while (!highlight.empty() && highlight[highlight.size() - 1] == ' ')
    highlight.resize(highlight.size() - 1);

  highlight += "\n";
  OutputString(highlight, DECORATION_BLUE);
}

}  // namespace

Err::Err() : has_error_(false) {
}

Err::Err(const Location& location,
         const std::string& msg,
         const std::string& help)
    : has_error_(true),
      location_(location),
      message_(msg),
      help_text_(help) {
}

Err::Err(const LocationRange& range,
         const std::string& msg,
         const std::string& help)
    : has_error_(true),
      location_(range.begin()),
      message_(msg),
      help_text_(help) {
  ranges_.push_back(range);
}

Err::Err(const Token& token,
         const std::string& msg,
         const std::string& help)
    : has_error_(true),
      location_(token.location()),
      message_(msg),
      help_text_(help) {
  ranges_.push_back(token.range());
}

Err::Err(const ParseNode* node,
         const std::string& msg,
         const std::string& help_text)
    : has_error_(true),
      message_(msg),
      help_text_(help_text) {
  // Node will be null in certain tests.
  if (node) {
    LocationRange range = node->GetRange();
    location_ = range.begin();
    ranges_.push_back(range);
  }
}

Err::Err(const Value& value,
         const std::string msg,
         const std::string& help_text)
    : has_error_(true),
      message_(msg),
      help_text_(help_text) {
  if (value.origin()) {
    LocationRange range = value.origin()->GetRange();
    location_ = range.begin();
    ranges_.push_back(range);
  }
}

Err::~Err() {
}

void Err::PrintToStdout() const {
  InternalPrintToStdout(false);
}

void Err::AppendSubErr(const Err& err) {
  sub_errs_.push_back(err);
}

void Err::InternalPrintToStdout(bool is_sub_err) const {
  DCHECK(has_error_);

  if (!is_sub_err)
    OutputString("ERROR ", DECORATION_RED);

  // File name and location.
  const InputFile* input_file = location_.file();
  std::string loc_str;
  if (input_file) {
    std::string path8;
    path8.assign(input_file->name().value());

    if (is_sub_err)
      loc_str = "See ";
    else
      loc_str = "at ";
    loc_str += path8 + ": " +
        base::IntToString(location_.line_number()) + ":" +
        base::IntToString(location_.char_offset()) + ": ";
  }
  OutputString(loc_str + message_ + "\n");

  // Quoted line.
  if (input_file) {
    std::string line = GetNthLine(input_file->contents(),
                                  location_.line_number());
    if (!ContainsOnlyWhitespaceASCII(line)) {
      OutputString(line + "\n", DECORATION_BOLD);
      OutputHighlighedPosition(location_, ranges_, line.size());
    }
  }

  // Optional help text.
  if (!help_text_.empty())
    OutputString(help_text_ + "\n");

  // Sub errors.
  for (size_t i = 0; i < sub_errs_.size(); i++)
    sub_errs_[i].InternalPrintToStdout(true);
}
