// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/tint/utils/diagnostic/formatter.h"

#include <algorithm>
#include <iterator>
#include <utility>
#include <vector>

#include "src/tint/utils/diagnostic/diagnostic.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/styled_text_printer.h"
#include "src/tint/utils/text/text_style.h"

namespace tint::diag {
namespace {

const char* ToString(Severity severity) {
    switch (severity) {
        case Severity::Note:
            return "note";
        case Severity::Warning:
            return "warning";
        case Severity::Error:
            return "error";
        case Severity::InternalCompilerError:
            return "internal compiler error";
        case Severity::Fatal:
            return "fatal";
    }
    return "";
}

std::string ToString(const Source::Location& location) {
    StringStream ss;
    if (location.line > 0) {
        ss << location.line;
        if (location.column > 0) {
            ss << ":" << location.column;
        }
    }
    return ss.str();
}

}  // namespace

Formatter::Formatter() {}
Formatter::Formatter(const Style& style) : style_(style) {}

StyledText Formatter::Format(const List& list) const {
    StyledText text;

    bool first = true;
    for (auto diag : list) {
        if (!first) {
            text << "\n";
        }
        Format(diag, text);
        first = false;
    }

    if (style_.print_newline_at_end) {
        text << "\n";
    }

    return text;
}

void Formatter::Format(const Diagnostic& diag, StyledText& text) const {
    auto const& src = diag.source;
    auto const& rng = src.range;

    text << style::Plain;
    TINT_DEFER(text << style::Plain);

    struct TextAndStyle {
        std::string text;
        TextStyle style = {};
    };
    Vector<TextAndStyle, 6> prefix;

    if (style_.print_file && src.file != nullptr) {
        if (rng.begin.line > 0) {
            prefix.Push(TextAndStyle{src.file->path + ":" + ToString(rng.begin)});
        } else {
            prefix.Push(TextAndStyle{src.file->path});
        }
    } else if (rng.begin.line > 0) {
        prefix.Push(TextAndStyle{ToString(rng.begin)});
    }

    if (style_.print_severity) {
        TextStyle style;
        switch (diag.severity) {
            case Severity::Note:
                break;
            case Severity::Warning:
                style = style::Warning + style::Bold;
                break;
            case Severity::Error:
                style = style::Error + style::Bold;
                break;
            case Severity::Fatal:
            case Severity::InternalCompilerError:
                style = style::Fatal + style::Bold;
                break;
        }
        prefix.Push(TextAndStyle{ToString(diag.severity), style});
    }

    for (size_t i = 0; i < prefix.Length(); i++) {
        if (i > 0) {
            text << " ";
        }
        text << prefix[i].style << prefix[i].text;
    }

    if (!prefix.IsEmpty()) {
        text << style::Plain << ": ";
    }
    text << style::Bold << diag.message;

    if (style_.print_line && src.file && rng.begin.line > 0) {
        text << style::Plain << "\n";

        for (size_t line_num = rng.begin.line;
             (line_num <= rng.end.line) && (line_num <= src.file->content.lines.size());
             line_num++) {
            auto& line = src.file->content.lines[line_num - 1];
            auto line_len = line.size();

            bool is_ascii = true;
            for (auto c : line) {
                if (c == '\t') {
                    text.Repeat(' ', style_.tab_width);
                } else {
                    text << c;
                }
                if (c & 0x80) {
                    is_ascii = false;
                }
            }

            text << style::Plain << "\n";

            // If the line contains non-ascii characters, then we cannot assume that
            // a single utf8 code unit represents a single glyph, so don't attempt to
            // draw squiggles.
            if (!is_ascii) {
                continue;
            }

            text << style::Squiggle;

            // Count the number of glyphs in the line span.
            // start and end use 1-based indexing.
            auto num_glyphs = [&](size_t start, size_t end) {
                size_t count = 0;
                start = (start > 0) ? (start - 1) : 0;
                end = (end > 0) ? (end - 1) : 0;
                for (size_t i = start; (i < end) && (i < line_len); i++) {
                    count += (line[i] == '\t') ? style_.tab_width : 1;
                }
                return count;
            };

            if (line_num == rng.begin.line && line_num == rng.end.line) {
                // Single line
                text.Repeat(' ', num_glyphs(1, rng.begin.column));
                text.Repeat('^', std::max<size_t>(num_glyphs(rng.begin.column, rng.end.column), 1));
            } else if (line_num == rng.begin.line) {
                // Start of multi-line
                text.Repeat(' ', num_glyphs(1, rng.begin.column));
                text.Repeat('^', num_glyphs(rng.begin.column, line_len + 1));
            } else if (line_num == rng.end.line) {
                // End of multi-line
                text.Repeat('^', num_glyphs(1, rng.end.column));
            } else {
                // Middle of multi-line
                text.Repeat('^', num_glyphs(1, line_len + 1));
            }
            text << style::Plain << "\n";
        }
    }
}

Formatter::~Formatter() = default;

}  // namespace tint::diag
