// Copyright 2017 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 "fidl/error_reporter.h"
#include "fidl/source_location.h"
#include "fidl/string_view.h"
#include "fidl/token.h"

namespace fidl {

std::string MakeSquiggle(const std::string& surrounding_line, int column) {
    std::string squiggle;
    for (int i = 0; i < column; i++) {
        switch (surrounding_line[i]) {
        case '\t':
            squiggle.push_back('\t');
            break;
        default:
            squiggle.push_back(' ');
        }
    }
    squiggle.push_back('^');
    return squiggle;
}

std::string Format(std::string qualifier, const SourceLocation& location,
                   StringView message, size_t squiggle_size = 0u) {
    SourceFile::Position position;
    std::string surrounding_line = location.SourceLine(&position);

    std::string squiggle = MakeSquiggle(surrounding_line, position.column);
    if (squiggle_size != 0u) {
        --squiggle_size;
    }
    squiggle += std::string(squiggle_size, '~');
    // Some tokens (like string literals) can span multiple
    // lines. Truncate the string to just one line at most. The
    // containing line contains a newline, so drop it when
    // comparing sizes.
    size_t line_size = surrounding_line.size() - 1;
    if (squiggle.size() > line_size) {
        squiggle.resize(line_size);
    }

    // Many editors and IDEs recognize errors in the form of
    // filename:linenumber:column: error: descriptive-test-here\n
    std::string error = location.position();
    error.append(": ");
    error.append(qualifier);
    error.append(": ");
    error.append(message);
    error.push_back('\n');
    error.append(surrounding_line);
    error.append(squiggle);

    return error;
}

// ReportError records an error with the location, message, source line, and
// position indicator.
//
//     filename:line:col: error: message
//     sourceline
//        ^
void ErrorReporter::ReportError(const SourceLocation& location, StringView message) {
    auto error = Format("error", location, message);
    errors_.push_back(std::move(error));
}

// ReportError records an error with the location, message, source line,
// position indicator, and tildes under the token reported.
//
//     filename:line:col: error: message
//     sourceline
//        ^~~~
void ErrorReporter::ReportError(const Token& token, StringView message) {
    auto token_location = token.location();
    auto token_data = token_location.data();
    auto error = Format("error", token_location, message, token_data.size());
    errors_.push_back(std::move(error));
}

// ReportError records the provided message.
void ErrorReporter::ReportError(StringView message) {
    std::string error("error: ");
    error.append(message);
    errors_.push_back(std::move(error));
}

// ReportWarning records a warning with the location, message, source line, and
// position indicator.
//
//     filename:line:col: warning: message
//     sourceline
//        ^
void ErrorReporter::ReportWarning(const SourceLocation& location, StringView message) {
    if (warnings_as_errors_) {
        ReportError(location, message);
        return;
    }
    auto error = Format("warning", location, message);
    warnings_.push_back(std::move(error));
}

void ErrorReporter::PrintReports() {
    for (const auto& error : errors_) {
        fprintf(stderr, "%s\n", error.data());
    }
    for (const auto& warning : warnings_) {
        fprintf(stderr, "%s\n", warning.data());
    }
}

} // namespace fidl
