/*
 * Copyright (c) 2019 The Khronos Group Inc.
 * Copyright (c) 2019 Valve Corporation
 * Copyright (c) 2019 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Charles Giessen <charles@lunarg.com>
 *
 */

#pragma once

#include <iomanip>
#include <iostream>
#include <ostream>
#include <stack>
#include <sstream>
#include <string>

#include <assert.h>

std::string insert_quotes(std::string s) { return "\"" + s + "\""; }

std::string to_string_16(const uint8_t uid[16]) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (int i = 0; i < 16; ++i) {
        if (i == 4 || i == 6 || i == 8 || i == 10) ss << '-';
        ss << std::setw(2) << static_cast<unsigned>(uid[i]);
    }
    return ss.str();
}

std::string to_string_8(const uint8_t uid[8]) {
    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (int i = 0; i < 8; ++i) {
        if (i == 4) ss << '-';
        ss << std::setw(2) << static_cast<unsigned>(uid[i]);
    }
    return ss.str();
}

std::string VkVersionString(uint32_t version) {
    uint32_t major = version >> 22;
    uint32_t minor = (version >> 12) & 0x3ff;
    uint32_t patch = version & 0xfff;
    return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch);
}

std::string VkVersionString(VulkanVersion v) {
    return std::to_string(v.major) + "." + std::to_string(v.minor) + "." + std::to_string(v.patch);
}

std::string VkConformanceVersionString(const VkConformanceVersion &c) {
    return std::to_string(c.major) + "." + std::to_string(c.minor) + "." + std::to_string(c.subminor) + "." +
           std::to_string(c.patch);
}

enum class OutputType { text, html, json, vkconfig_output };

struct PrinterCreateDetails {
    OutputType output_type = OutputType::text;
    bool print_to_file = false;
    std::string file_name = "vulkaninfo.txt";
    std::string start_string = "";
};

class Printer {
  public:
    Printer(const PrinterCreateDetails &details, std::ostream &out, const VulkanVersion vulkan_version)
        : output_type(details.output_type), out(out) {
        StackNode node{};
        node.is_first_item = false;
        node.indents = 0;
        switch (output_type) {
            case (OutputType::text):
                out << "==========\n";
                out << "VULKANINFO\n";
                out << "==========\n\n";
                out << "Vulkan Instance Version: " << VkVersionString(vulkan_version) << "\n\n\n";

                break;
            case (OutputType::html):
                out << "<!doctype html>\n";
                out << "<html lang='en'>\n";
                out << "\t<head>\n";
                out << "\t\t<title>vulkaninfo</title>\n";
                out << "\t\t<style>\n";
                out << "\t\thtml {\n";
                out << "\t\t\tbackground-color: #0b1e48;\n";
                out << "\t\t\tbackground-image: url(\"https://vulkan.lunarg.com/img/bg-starfield.jpg\");\n";
                out << "\t\t\tbackground-position: center;\n";
                out << "\t\t\t-webkit-background-size: cover;\n";
                out << "\t\t\t-moz-background-size: cover;\n";
                out << "\t\t\t-o-background-size: cover;\n";
                out << "\t\t\tbackground-size: cover;\n";
                out << "\t\t\tbackground-attachment: fixed;\n";
                out << "\t\t\tbackground-repeat: no-repeat;\n";
                out << "\t\t\theight: 100%;\n";
                out << "\t\t}\n";
                out << "\t\t#header {\n";
                out << "\t\t\tz-index: -1;\n";
                out << "\t\t}\n";
                out << "\t\t#header>img {\n";
                out << "\t\t\tposition: absolute;\n";
                out << "\t\t\twidth: 160px;\n";
                out << "\t\t\tmargin-left: -280px;\n";
                out << "\t\t\ttop: -10px;\n";
                out << "\t\t\tleft: 50%;\n";
                out << "\t\t}\n";
                out << "\t\t#header>h1 {\n";
                out << "\t\t\tfont-family: Arial, \"Helvetica Neue\", Helvetica, sans-serif;\n";
                out << "\t\t\tfont-size: 44px;\n";
                out << "\t\t\tfont-weight: 200;\n";
                out << "\t\t\ttext-shadow: 4px 4px 5px #000;\n";
                out << "\t\t\tcolor: #eee;\n";
                out << "\t\t\tposition: absolute;\n";
                out << "\t\t\twidth: 400px;\n";
                out << "\t\t\tmargin-left: -80px;\n";
                out << "\t\t\ttop: 8px;\n";
                out << "\t\t\tleft: 50%;\n";
                out << "\t\t}\n";
                out << "\t\tbody {\n";
                out << "\t\t\tfont-family: Consolas, monaco, monospace;\n";
                out << "\t\t\tfont-size: 14px;\n";
                out << "\t\t\tline-height: 20px;\n";
                out << "\t\t\tcolor: #eee;\n";
                out << "\t\t\theight: 100%;\n";
                out << "\t\t\tmargin: 0;\n";
                out << "\t\t\toverflow: hidden;\n";
                out << "\t\t}\n";
                out << "\t\t#wrapper {\n";
                out << "\t\t\tbackground-color: rgba(0, 0, 0, 0.7);\n";
                out << "\t\t\tborder: 1px solid #446;\n";
                out << "\t\t\tbox-shadow: 0px 0px 10px #000;\n";
                out << "\t\t\tpadding: 8px 12px;\n\n";
                out << "\t\t\tdisplay: inline-block;\n";
                out << "\t\t\tposition: absolute;\n";
                out << "\t\t\ttop: 80px;\n";
                out << "\t\t\tbottom: 25px;\n";
                out << "\t\t\tleft: 50px;\n";
                out << "\t\t\tright: 50px;\n";
                out << "\t\t\toverflow: auto;\n";
                out << "\t\t}\n";
                out << "\t\tdetails>details {\n";
                out << "\t\t\tmargin-left: 22px;\n";
                out << "\t\t}\n";
                out << "\t\tdetails>summary:only-child::-webkit-details-marker {\n";
                out << "\t\t\tdisplay: none;\n";
                out << "\t\t}\n";
                out << "\t\t.var, .type, .val {\n";
                out << "\t\t\tdisplay: inline;\n";
                out << "\t\t}\n";
                out << "\t\t.var {\n";
                out << "\t\t}\n";
                out << "\t\t.type {\n";
                out << "\t\t\tcolor: #acf;\n";
                out << "\t\t\tmargin: 0 12px;\n";
                out << "\t\t}\n";
                out << "\t\t.val {\n";
                out << "\t\t\tcolor: #afa;\n";
                out << "\t\t\tbackground: #222;\n";
                out << "\t\t\ttext-align: right;\n";
                out << "\t\t}\n";
                out << "\t\t</style>\n";
                out << "\t</head>\n";
                out << "\t<body>\n";
                out << "\t\t<div id='header'>\n";
                out << "\t\t\t<h1>vulkaninfo</h1>\n";
                out << "\t\t</div>\n";
                out << "\t\t<div id='wrapper'>\n";
                out << "\t\t\t<details><summary>Vulkan Instance Version: <span class='val'>" << VkVersionString(vulkan_version)
                    << "</span></summary></details>\n\t\t\t<br />\n";
                node.indents = 3;
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                out << details.start_string;
                node.indents = 1;
                break;
            default:
                break;
        }
        object_stack.push(node);
    }
    ~Printer() {
        switch (output_type) {
            case (OutputType::text):
                break;
            case (OutputType::html):
                out << "\t\t</div>\n";
                out << "\t</body>\n";
                out << "</html>\n";
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                out << "\n}\n";
                break;
        }
        assert(!object_stack.empty() && "mismatched number of ObjectStart/ObjectEnd or ArrayStart/ArrayEnd's");
        object_stack.pop();
        assert(object_stack.empty() && "indents must be zero at program end");
    };

    Printer(const Printer &) = delete;
    const Printer &operator=(const Printer &) = delete;

    OutputType Type() { return output_type; }

    // When an error occurs, call this to create a valid output file. Needed for json/html
    void FinishOutput() {
        while (!object_stack.empty()) {
            switch (output_type) {
                case (OutputType::text):
                    break;
                case (OutputType::html):
                    while (get_top().indents > 3) {
                        out << "</details>\n";
                    }
                    break;
                case (OutputType::json):
                case (OutputType::vkconfig_output):
                    out << "\n" << std::string(static_cast<size_t>(get_top().indents), '\t');
                    if (get_top().is_array) {
                        out << "]";
                    } else {
                        out << "}";
                    }
                    break;
                default:
                    break;
            }
            object_stack.pop();
        }
    }

    // Custom Formatting
    // use by prepending with p.SetXXX().ObjectStart/ArrayStart

    Printer &SetHeader() {
        get_top().set_next_header = true;
        return *this;
    }

    Printer &SetSubHeader() {
        get_top().set_next_subheader = true;
        return *this;
    }

    Printer &SetOpenDetails() {
        get_top().set_details_open = true;
        return *this;
    }

    Printer &SetAlwaysOpenDetails(bool value = true) {
        get_top().should_always_open = value;
        return *this;
    }

    Printer &SetTitleAsType() {
        get_top().set_object_name_as_type = true;
        return *this;
    }

    Printer &SetAsType() {
        get_top().set_as_type = true;
        return *this;
    }

    Printer &SetIgnoreMinWidthInChild() {
        get_top().ignore_min_width_parameter_in_child = true;
        return *this;
    }

    Printer &SetMinKeyWidth(size_t min_key_width) {
        get_top().min_key_width = min_key_width;
        return *this;
    }

    Printer &SetElementIndex(int index) {
        assert(index >= 0 && "cannot set element index to a negative value");
        get_top().element_index = index;
        return *this;
    }

    void ObjectStart(std::string object_name, int32_t count_subobjects = -1) {
        switch (output_type) {
            case (OutputType::text): {
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << object_name;
                if (get_top().element_index != -1) {
                    out << "[" << get_top().element_index << "]";
                }
                out << ":";
                if (count_subobjects >= 0) {
                    out << " count = " << count_subobjects;
                }
                out << "\n";
                size_t headersize = object_name.size() + 1;
                if (count_subobjects >= 0) {
                    headersize += 9 + std::to_string(count_subobjects).size();
                }
                if (get_top().element_index != -1) {
                    headersize += 2 + std::to_string(get_top().element_index).size();
                    get_top().element_index = -1;
                }
                PrintHeaderUnderlines(headersize);
                break;
            }
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t');
                if (get_top().set_details_open || get_top().should_always_open) {
                    out << "<details open>";
                    get_top().set_details_open = false;
                } else {
                    out << "<details>";
                }
                out << "<summary>";
                if (get_top().set_object_name_as_type) {
                    out << "<span class='type'>" << object_name << "</span>";
                    get_top().set_object_name_as_type = false;
                } else {
                    out << object_name;
                }
                if (get_top().element_index != -1) {
                    out << "[<span class='val'>" << get_top().element_index << "</span>]";
                    get_top().element_index = -1;
                }
                if (count_subobjects >= 0) {
                    out << ": count = <span class='val'>" << std::to_string(count_subobjects) << "</span>";
                }
                out << "</summary>\n";
                break;
            case (OutputType::json):
                if (!get_top().is_first_item) {
                    out << ",\n";
                } else {
                    get_top().is_first_item = false;
                }
                out << std::string(static_cast<size_t>(get_top().indents), '\t');
                // Objects with no name are elements in an array of objects
                if (object_name == "" || get_top().element_index != -1) {
                    out << "{\n";
                    get_top().element_index = -1;
                } else {
                    out << "\"" << object_name << "\": {\n";
                }
                break;
            case (OutputType::vkconfig_output):
                if (!get_top().is_first_item) {
                    out << ",\n";
                } else {
                    get_top().is_first_item = false;
                }
                out << std::string(static_cast<size_t>(get_top().indents), '\t');

                if (get_top().element_index != -1) {
                    out << "\"" << object_name << "[" << get_top().element_index << "]\": {\n";
                    get_top().element_index = -1;
                } else {
                    out << "\"" << object_name << "\": {\n";
                }
                break;
            default:
                break;
        }
        push_node(false);
    }
    void ObjectEnd() {
        assert(get_top().is_array == false && "cannot call ObjectEnd while inside an Array");
        object_stack.pop();
        assert(get_top().indents >= 0 && "indents cannot go below zero");
        switch (output_type) {
            case (OutputType::text):

                break;
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "</details>\n";
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                out << "\n" << std::string(static_cast<size_t>(get_top().indents), '\t') << "}";
                break;
            default:
                break;
        }
    }
    void ArrayStart(std::string array_name, size_t element_count = 0) {
        switch (output_type) {
            case (OutputType::text): {
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << array_name << ":";
                size_t underline_count = array_name.size() + 1;
                if (element_count > 0) {
                    out << " count = " << element_count;
                    underline_count += 9 + std::to_string(element_count).size();
                }
                out << "\n";
                PrintHeaderUnderlines(underline_count);
                break;
            }
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t');
                if (get_top().set_details_open || get_top().should_always_open) {
                    out << "<details open>";
                    get_top().set_details_open = false;
                } else {
                    out << "<details>";
                }
                out << "<summary>" << array_name;
                if (element_count > 0) {
                    out << ": count = <span class='val'>" << element_count << "</span>";
                }
                out << "</summary>\n";
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                if (!get_top().is_first_item) {
                    out << ",\n";
                } else {
                    get_top().is_first_item = false;
                }
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "\"" << array_name << "\": "
                    << "[\n";
                assert(get_top().is_array == false &&
                       "Cant start an array object inside another array, must be enclosed in an object");
                break;
            default:
                break;
        }
        push_node(true);
    }
    void ArrayEnd() {
        assert(get_top().is_array == true && "cannot call ArrayEnd while inside an Object");
        object_stack.pop();
        assert(get_top().indents >= 0 && "indents cannot go below zero");
        switch (output_type) {
            case (OutputType::text):
                break;
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "</details>\n";
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                out << "\n" << std::string(static_cast<size_t>(get_top().indents), '\t') << "]";
                break;
            default:
                break;
        }
    }

    // For printing key-value pairs.
    // value_description is for reference information and is displayed inside parenthesis after the value
    template <typename T>
    void PrintKeyValue(std::string key, T value, std::string value_description = "") {
        switch (output_type) {
            case (OutputType::text):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << key;
                if (get_top().min_key_width > key.size() && !get_top().ignore_min_width_parameter) {
                    out << std::string(get_top().min_key_width - key.size(), ' ');
                }
                out << " = " << value;
                if (value_description != "") {
                    out << " (" << value_description << ")";
                }
                out << "\n";
                break;
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "<details><summary>" << key;
                if (get_top().min_key_width > key.size()) {
                    out << std::string(get_top().min_key_width - key.size(), ' ');
                }
                if (get_top().set_as_type) {
                    get_top().set_as_type = false;
                    out << " = <span class='type'>" << value << "</span>";
                } else {
                    out << " = <span class='val'>" << value << "</span>";
                }
                if (value_description != "") {
                    out << " (<span class='val'>" << value_description << "</span>)";
                }
                out << "</summary></details>\n";
                break;
            case (OutputType::json):
                if (!get_top().is_first_item) {
                    out << ",\n";
                } else {
                    get_top().is_first_item = false;
                }
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "\"" << key << "\": " << value;
                break;
            case (OutputType::vkconfig_output):
                if (!get_top().is_first_item) {
                    out << ",\n";
                } else {
                    get_top().is_first_item = false;
                }
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "\"" << key << "\": ";
                if (value_description != "") {
                    out << "\"" << value << " (" << value_description << ")\"";
                } else {
                    out << value;
                }
            default:
                break;
        }
    }

    // For printing key - string pairs (necessary because of json)
    void PrintKeyString(std::string key, std::string value, std::string value_description = "") {
        switch (output_type) {
            case (OutputType::text):
            case (OutputType::html):
                PrintKeyValue(key, value, value_description);
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                PrintKeyValue(key, std::string("\"") + value + "\"", value_description);
                break;
            default:
                break;
        }
    }

    // For printing key - string pairs (necessary because of json)
    void PrintKeyBool(std::string key, bool value, std::string value_description = "") {
        PrintKeyValue(key, value ? "true" : "false", value_description);
    }

    // print inside array
    template <typename T>
    void PrintElement(T element, std::string value_description = "") {
        switch (output_type) {
            case (OutputType::text):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << element;
                if (value_description != "") {
                    out << " (" << value_description << ")";
                }
                out << "\n";
                break;
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "<details><summary>";
                if (get_top().set_as_type) {
                    get_top().set_as_type = false;
                    out << "<span class='type'>" << element << "</span>";
                } else {
                    out << "<span class='val'>" << element << "</span>";
                }
                if (value_description != "") {
                    out << " (<span class='val'>" << value_description << "</span>)";
                }
                out << "</summary></details>\n";
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                if (!get_top().is_first_item) {
                    out << ",\n";
                } else {
                    get_top().is_first_item = false;
                }
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << element;
                break;
            default:
                break;
        }
    }
    void PrintString(std::string string, std::string value_description = "") {
        switch (output_type) {
            case (OutputType::text):
            case (OutputType::html):
                PrintElement(string, value_description);
                break;
            case (OutputType::json):
            case (OutputType::vkconfig_output):
                PrintElement("\"" + string + "\"", value_description);
            default:
                break;
        }
    }
    void PrintExtension(std::string ext_name, uint32_t revision, size_t min_width = 0) {
        switch (output_type) {
            case (OutputType::text):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << ext_name
                    << std::string(min_width - ext_name.size(), ' ') << " : extension revision " << revision << "\n";
                break;
            case (OutputType::html):
                out << std::string(static_cast<size_t>(get_top().indents), '\t') << "<details><summary>" << DecorateAsType(ext_name)
                    << std::string(min_width - ext_name.size(), ' ') << " : extension revision "
                    << DecorateAsValue(std::to_string(revision)) << "</summary></details>\n";
                break;
            case (OutputType::json):
                PrintKeyValue(ext_name, revision);
                break;
            case (OutputType::vkconfig_output):
                ObjectStart(ext_name);
                PrintKeyValue("specVersion", revision);
                ObjectEnd();
                break;
            default:
                break;
        }
    }
    void AddNewline() {
        if (output_type == OutputType::text) {
            out << "\n";
        }
    }
    void IndentIncrease() {
        if (output_type == OutputType::text) {
            get_top().indents++;
        }
    }
    void IndentDecrease() {
        if (output_type == OutputType::text) {
            get_top().indents--;
            assert(get_top().indents >= 0 && "indents cannot go below zero");
        }
    }

    std::string DecorateAsType(const std::string &input) {
        if (output_type == OutputType::html)
            return "<span class='type'>" + input + "</span>";
        else
            return input;
    }

    std::string DecorateAsValue(const std::string &input) {
        if (output_type == OutputType::html)
            return "<span class='val'>" + input + "</span>";
        else
            return input;
    }

  protected:
    OutputType output_type;
    std::ostream &out;

    struct StackNode {
        int indents = 0;

        // header, subheader
        bool set_next_header = false;
        bool set_next_subheader = false;

        // html coloring
        bool set_as_type = false;

        // open <details>
        bool set_details_open = false;

        // always open <details>
        bool should_always_open = false;

        // make object titles the color of types
        bool set_object_name_as_type = false;

        // ignores the min_width parameter
        bool ignore_min_width_parameter = false;

        // sets the next created object/child to ignore the min_width parameter
        bool ignore_min_width_parameter_in_child = false;

        // keep track of the spacing between names and values
        size_t min_key_width = 0;

        // objects which are in an array
        int element_index = -1;  // negative one is the sentinel value

        // json
        bool is_first_item;  // for json: for adding a comma in between objects
        bool is_array;       // for json: match pairs of {}'s and []'s
    };

    // Contains the details about the current 'object' in the tree
    std::stack<StackNode> object_stack;

    // Helper to get the current top of the object_stack
    StackNode &get_top() { return object_stack.top(); }

    // can only be called after a node was manually pushed onto the stack in the constructor
    void push_node(bool array) {
        StackNode node{};
        node.indents = get_top().indents + 1;
        node.is_array = array;
        node.is_first_item = true;
        node.ignore_min_width_parameter = get_top().ignore_min_width_parameter_in_child;
        object_stack.push(node);
    }

    // utility
    void PrintHeaderUnderlines(size_t length) {
        assert(get_top().indents >= 0 && "indents must not be negative");
        assert(length <= 10000 && "length shouldn't be unreasonably large");
        if (get_top().set_next_header) {
            out << std::string(static_cast<size_t>(get_top().indents), '\t') << std::string(length, '=') << "\n";
            get_top().set_next_header = false;
        } else if (get_top().set_next_subheader) {
            out << std::string(static_cast<size_t>(get_top().indents), '\t') << std::string(length, '-') << "\n";
            get_top().set_next_subheader = false;
        }
    }
};
// Purpose: When a Printer starts an object or array it will automatically indent the output. This isn't
// always desired, requiring a manual decrease of indention. This wrapper facilitates that while also
// automatically re-indenting the output to the previous indent level on scope exit.
class IndentWrapper {
  public:
    IndentWrapper(Printer &p) : p(p) {
        if (p.Type() == OutputType::text) p.IndentDecrease();
    }
    ~IndentWrapper() {
        if (p.Type() == OutputType::text) p.IndentIncrease();
    }

  private:
    Printer &p;
};

class ObjectWrapper {
  public:
    ObjectWrapper(Printer &p, std::string object_name) : p(p) { p.ObjectStart(object_name); }
    ObjectWrapper(Printer &p, std::string object_name, size_t count_subobjects) : p(p) {
        p.ObjectStart(object_name, static_cast<int32_t>(count_subobjects));
    }
    ~ObjectWrapper() { p.ObjectEnd(); }

  private:
    Printer &p;
};

class ArrayWrapper {
  public:
    ArrayWrapper(Printer &p, std::string array_name, size_t element_count = 0) : p(p) { p.ArrayStart(array_name, element_count); }
    ~ArrayWrapper() { p.ArrayEnd(); }

  private:
    Printer &p;
};
