// 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.

// GEN_BUILD:CONDITION(tint_build_is_win)

#include <cstring>

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

#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>

namespace tint::diag {
namespace {

struct ConsoleInfo {
    HANDLE handle = INVALID_HANDLE_VALUE;
    WORD default_attributes = 0;
    operator bool() const { return handle != INVALID_HANDLE_VALUE; }
};

ConsoleInfo ConsoleInfoFor(FILE* file) {
    if (file == nullptr) {
        return {};
    }

    ConsoleInfo console{};
    if (file == stdout) {
        console.handle = GetStdHandle(STD_OUTPUT_HANDLE);
    } else if (file == stderr) {
        console.handle = GetStdHandle(STD_ERROR_HANDLE);
    } else {
        return {};
    }

    CONSOLE_SCREEN_BUFFER_INFO info{};
    if (GetConsoleScreenBufferInfo(console.handle, &info) == 0) {
        return {};
    }

    console.default_attributes = info.wAttributes;
    return console;
}

class PrinterWindows : public Printer {
  public:
    PrinterWindows(FILE* f, bool use_colors)
        : file(f), console(ConsoleInfoFor(use_colors ? f : nullptr)) {}

    void Write(const std::string& str, const Style& style) override {
        WriteColor(style.color, style.bold);
        fwrite(str.data(), 1, str.size(), file);
        WriteColor(Color::kDefault, false);
    }

  private:
    WORD Attributes(Color color, bool bold) {
        switch (color) {
            case Color::kDefault:
                return console.default_attributes;
            case Color::kBlack:
                return 0;
            case Color::kRed:
                return FOREGROUND_RED | (bold ? FOREGROUND_INTENSITY : 0);
            case Color::kGreen:
                return FOREGROUND_GREEN | (bold ? FOREGROUND_INTENSITY : 0);
            case Color::kYellow:
                return FOREGROUND_RED | FOREGROUND_GREEN | (bold ? FOREGROUND_INTENSITY : 0);
            case Color::kBlue:
                return FOREGROUND_BLUE | (bold ? FOREGROUND_INTENSITY : 0);
            case Color::kMagenta:
                return FOREGROUND_RED | FOREGROUND_BLUE | (bold ? FOREGROUND_INTENSITY : 0);
            case Color::kCyan:
                return FOREGROUND_GREEN | FOREGROUND_BLUE | (bold ? FOREGROUND_INTENSITY : 0);
            case Color::kWhite:
                return FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
                       (bold ? FOREGROUND_INTENSITY : 0);
        }
        return 0;  // unreachable
    }

    void WriteColor(Color color, bool bold) {
        if (console) {
            SetConsoleTextAttribute(console.handle, Attributes(color, bold));
            fflush(file);
        }
    }

    FILE* const file;
    const ConsoleInfo console;
};

}  // namespace

std::unique_ptr<Printer> Printer::Create(FILE* out, bool use_colors) {
    return std::make_unique<PrinterWindows>(out, use_colors);
}

}  // namespace tint::diag
