// 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 "tools/fidl/fidlc/src/findings_json.h"

namespace fidlc {

void FindingsJson::Generate(const Finding& finding) {
  GenerateObject([&]() {
    GenerateObjectMember("category", "fidl-lint/" + finding.subcategory(), Position::kFirst);
    GenerateObjectMember("message", finding.message());
    // TODO(https://fxbug.dev/42160183) Add "url" to related FIDL documentation, per Tricium spec
    Generate(finding.span());
    std::vector<SuggestionWithReplacementSpan> suggestions;
    if (finding.suggestion().has_value()) {
      suggestions.emplace_back(
          SuggestionWithReplacementSpan{finding.span(), finding.suggestion().value()});
    }
    GenerateObjectMember("suggestions", suggestions);
  });
}

void FindingsJson::Generate(const SuggestionWithReplacementSpan& suggestion_with_span) {
  auto& suggestion = suggestion_with_span.suggestion;
  auto& span = suggestion_with_span.span;
  GenerateObject([&]() {
    GenerateObjectMember("description", suggestion.description(), Position::kFirst);
    std::vector<Replacement> replacements;
    if (suggestion.replacement().has_value()) {
      replacements.emplace_back(Replacement{span, suggestion.replacement().value()});
    }
    GenerateObjectMember("replacements", replacements);
  });
}

void FindingsJson::Generate(const Replacement& replacement) {
  GenerateObject([&]() {
    GenerateObjectMember("replacement", replacement.replacement, Position::kFirst);
    Generate(replacement.span);
  });
}

void FindingsJson::Generate(const SourceSpan& span) {
  GenerateObjectMember("path", span.source_file().filename());

  auto start = span.data();
  auto end = span.data();
  end.remove_prefix(start.size());

  // Gracefully handle a span indicating the end of the file.
  //
  // If the span starts at the end of the file, `end_span` should be the same as
  // `span`, or calling SourceSpan::position() will attempt to read past the end
  // of the source file.
  SourceSpan end_span;
  auto end_of_file = span.source_file().data().data() + span.source_file().data().size();
  if (start.data() == end_of_file) {
    end_span = span;
  } else {
    end_span = SourceSpan(end, span.source_file());
  }

  SourceFile::Position start_position = span.position();
  SourceFile::Position end_position = end_span.position();

  GenerateObjectMember("start_line", static_cast<uint32_t>(start_position.line));
  GenerateObjectMember("start_char", static_cast<uint32_t>(start_position.column - 1));
  GenerateObjectMember("end_line", static_cast<uint32_t>(end_position.line));
  GenerateObjectMember("end_char", static_cast<uint32_t>(end_position.column - 1));
}

std::ostringstream FindingsJson::Produce() {
  ResetIndentLevel();

  GenerateArray(findings_);

  return std::move(json_file_);
}

}  // namespace fidlc
