<!doctype html>
<!--
 Copyright 2022 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.
-->

<html>

<head>
    <title>Dawn Code Coverage viewer</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.0/codemirror.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.0/theme/seti.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.0/codemirror.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.0/mode/clike/clike.min.js"></script>
    <script src=https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.10/pako.min.js></script>

    <style>
        ::-webkit-scrollbar {
            background-color: #30353530;
        }

        ::-webkit-scrollbar-thumb {
            background-color: #80858050;
        }

        ::-webkit-scrollbar-corner {
            background-color: #00000000;
        }

        .frame {
            display: flex;
            left: 0px;
            right: 0px;
            top: 0px;
            bottom: 0px;
            position: absolute;
            font-family: monospace;
            background-color: #151515;
            color: #c0b070;
        }

        .left-pane {
            flex: 1;
        }

        .center-pane {
            flex: 3;
            min-width: 0;
            min-height: 0;
        }

        .top-pane {
            flex: 1;
            overflow: scroll;
        }

        .v-flex {
            display: flex;
            height: 100%;
            flex-direction: column;
        }

        .file-tree {
            font-size: small;
            overflow: auto;
            padding: 5px;
        }

        .test-tree {
            font-size: small;
            overflow: auto;
            padding: 5px;
        }

        .CodeMirror {
            flex: 3;
            height: 100%;
            border: 1px solid #eee;
        }

        .file-div {
            margin: 0px;
            white-space: nowrap;
            padding: 2px;
            margin-top: 1px;
            margin-bottom: 1px;
        }

        .file-div:hover {
            background-color: #303030;
            cursor: pointer;
        }

        .file-div.selected {
            background-color: #505050;
            color: #f0f0a0;
            cursor: pointer;
        }

        .test-name {
            margin: 0px;
            white-space: nowrap;
            padding: 2px;
            margin-top: 1px;
            margin-bottom: 1px;
        }

        .file-coverage {
            color: black;
            width: 20pt;
            padding-right: 3pt;
            padding-left: 3px;
            margin-right: 5pt;
            display: inline-block;
            text-align: center;
            border-radius: 5px;
        }

        .with-coverage {
            background-color: #20d04080;
            border-width: 0px 0px 0px 0px;
        }

        .with-coverage-start {
            border-left: solid 1px;
            border-color: #20f02080;
            margin-left: -1px;
        }

        .with-coverage-end {
            border-right: solid 1px;
            border-color: #20f02080;
            margin-right: -1px;
        }

        .without-coverage {
            background-color: #d0204080;
            border-width: 0px 0px 0px 0px;
        }

        .without-coverage-start {
            border-left: solid 1px;
            border-color: #f0202080;
            margin-left: -1px;
        }

        .without-coverage-end {
            border-right: solid 1px;
            border-color: #f0202080;
            margin-right: -1px;
        }
    </style>
</head>

<body>
    <div class="frame">
        <div id="file_tree" class="left-pane file-tree"></div>
        <div class="center-pane">
            <div id="source" class="v-flex">
                <div class="top-pane">
                    <div class="test-tree" id="test_tree"></div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // "Download" the coverage.dat file if the user presses ctrl-s
        document.addEventListener('keydown', e => {
            if (e.ctrlKey && e.key === 's') {
                e.preventDefault();
                window.open("coverage.dat");
            }
        });

        let current = {
            file: "",
            start_line: 0,
            start_column: 0,
            end_line: 0,
            end_column: 0,
        };

        let pending = { ...current };
        {
            let url = new URL(location.href);
            let query_string = url.search;
            let search_params = new URLSearchParams(query_string);
            var f = search_params.get('f');
            var s = search_params.get('s');
            var e = search_params.get('e');
            if (f) {
                pending.file = f;
            }
            if (s) {
                s = s.split('.');
                pending.start_line = s.length > 0 ? parseInt(s[0]) : 0;
                pending.start_column = s.length > 1 ? parseInt(s[1]) : 0;
            }
            if (e) {
                e = e.split('.');
                pending.end_line = e.length > 0 ? parseInt(e[0]) : 0;
                pending.end_column = e.length > 1 ? parseInt(e[1]) : 0;
            }
        };

        let set_location = (file, start_line, start_column, end_line, end_column) => {
            current.file = file;
            current.start_line = start_line;
            current.start_column = start_column;
            current.end_line = end_line;
            current.end_column = end_column;

            let url = new URL(location.href);
            let query_string = url.search;
            // Don't use URLSearchParams, as it will unnecessarily escape
            // characters, such as '/'.
            url.search = "f=" + file +
                "&s=" + start_line + "." + end_line +
                "&e=" + end_line + "." + end_column;
            window.history.replaceState(null, "", url.toString());
        };

        let before = (line, col, span) => {
            if (line < span[0]) { return true; }
            if (line == span[0]) { return col < span[1]; }
            return false;
        };

        let after = (line, col, span) => {
            if (line > span[2]) { return true; }
            if (line == span[2]) { return col > span[3]; }
            return false;
        };

        let intersects = (span, from, to) => {
            if (!before(to.line + 1, to.ch + 1, span) &&
                !after(from.line + 1, from.ch + 1, span)) {
                return true;
            }
            return false;
        };

        let el_file_tree = document.getElementById("file_tree");
        let el_test_tree = document.getElementById("test_tree");
        let el_source = CodeMirror(document.getElementById("source"), {
            lineNumbers: true,
            theme: "seti",
            mode: "text/x-c++src",
            readOnly: true,
        });

        addEventListener('beforeunload', () => {
            fetch("viewer.closed");
        });

        window.onload = function () {
            el_source.doc.setValue("// Loading... ");
            fetch("coverage.dat").then(response =>
                response.arrayBuffer()
            ).then(compressed =>
                pako.inflate(new Uint8Array(compressed))
            ).then(decompressed =>
                JSON.parse(new TextDecoder("utf-8").decode(decompressed))
            ).then(json => {
                el_source.doc.setValue("// Select file from the left... ");

                let revision = json.r;
                let names = json.n;
                let tests = json.t;
                let spans = json.s;
                let files = json.f;

                let glob_group = (file, groupID, span_ids) => {
                    while (true) {
                        let group = file.g[groupID];
                        group.s.forEach(span_id => span_ids.add(span_id));
                        if (!group.e) {
                            break;
                        }
                        groupID = group.e;
                    };
                };

                let coverage_spans = (file, data, span_ids) => {
                    if (data.g != undefined) {
                        glob_group(file, data.g, span_ids);
                    }
                    if (data.s != undefined) {
                        data.s.forEach(span_id => span_ids.add(span_id));
                    }
                };

                let glob_node = (file, nodes, span_ids) => {
                    nodes.forEach(node => {
                        let data = node[1];
                        coverage_spans(file, data, span_ids);
                        if (data.c) {
                            glob_node(file, data.c, span_ids);
                        }
                    });
                };

                let markup = file => {
                    if (file.u) {
                        for (span of file.u) {
                            el_source.doc.markText(
                                { "line": span[0] - 1, "ch": span[1] - 1 },
                                { "line": span[2] - 1, "ch": span[3] - 1 },
                                {
                                    // inclusiveLeft: true,
                                    className: "without-coverage",
                                    startStyle: "without-coverage-start",
                                    endStyle: "without-coverage-end",
                                });
                        }
                    }
                    let span_ids = new Set();
                    glob_node(file, file.c, span_ids);
                    el_source.operation(() => {
                        span_ids.forEach((span_id) => {
                            let span = spans[span_id];
                            el_source.doc.markText(
                                { "line": span[0] - 1, "ch": span[1] - 1 },
                                { "line": span[2] - 1, "ch": span[3] - 1 },
                                {
                                    // inclusiveLeft: true,
                                    className: "with-coverage",
                                    startStyle: "with-coverage-start",
                                    endStyle: "with-coverage-end",
                                });
                        });
                    });
                };

                let NONE_OVERLAP = 0;
                let ALL_OVERLAP = 1;
                let SOME_OVERLAP = 2;

                let gather_overlaps = (parent, file, coverage_nodes, from, to) => {
                    if (!coverage_nodes) { return; }

                    // Start by populating all the children nodes from the full
                    // test lists. This includes nodes that do not have child
                    // coverage data.
                    for (var index = 0; index < parent.test.length; index++) {
                        if (parent.children.has(index)) { continue; }

                        let test_node = parent.test[index];
                        let test_name_id = test_node[0];
                        let test_name = names[test_name_id];
                        let test_children = test_node[1];

                        let node = {
                            test: test_children,
                            name: parent.name ? parent.name + test_name : test_name,
                            overlaps: new Map(parent.overlaps), // map: span_id -> OVERLAP
                            children: new Map(), // map: index -> struct
                            is_leaf: test_children.length == 0,
                        };
                        parent.children.set(index, node);
                    }

                    // Now update the children that do have coverage data.
                    for (const coverage_node of coverage_nodes) {
                        let index = coverage_node[0];
                        let coverage = coverage_node[1];
                        let node = parent.children.get(index);

                        let span_ids = new Set();
                        coverage_spans(file, coverage, span_ids);

                        // Update the node overlaps based on the coverage spans.
                        for (const span_id of span_ids) {
                            if (intersects(spans[span_id], from, to)) {
                                let overlap = parent.overlaps.get(span_id) || NONE_OVERLAP;
                                overlap = (overlap == NONE_OVERLAP) ? ALL_OVERLAP : NONE_OVERLAP;
                                node.overlaps.set(span_id, overlap);
                            }
                        }

                        // Generate the child nodes.
                        gather_overlaps(node, file, coverage.c, from, to);

                        // Gather all the spans used by the children.
                        let all_spans = new Set();
                        for (const [_, child] of node.children) {
                            for (const [span, _] of child.overlaps) {
                                all_spans.add(span);
                            }
                        }

                        // Update the node.overlaps based on the child overlaps.
                        for (const span of all_spans) {
                            let overlap = undefined;
                            for (const [_, child] of node.children) {
                                let child_overlap = child.overlaps.get(span);
                                child_overlap = (child_overlap == undefined) ? NONE_OVERLAP : child_overlap;
                                if (overlap == undefined) {
                                    overlap = child_overlap;
                                } else {
                                    overlap = (child_overlap == overlap) ? overlap : SOME_OVERLAP
                                }
                            }
                            node.overlaps.set(span, overlap);
                        }

                        // If all the node.overlaps are NONE_OVERLAP or ALL_OVERLAP
                        // then there's no point holding on to the children -
                        // we know all transitive children either fully overlap
                        // or don't at all.
                        let some_overlap = false;
                        for (const [_, overlap] of node.overlaps) {
                            if (overlap == SOME_OVERLAP) {
                                some_overlap = true;
                                break;
                            }
                        }

                        if (!some_overlap) {
                            node.children = null;
                        }
                    }
                };

                let gather_tests = (file, coverage_nodes, test_nodes, from, to) => {
                    let out = [];

                    let traverse = (parent) => {
                        for (const [idx, node] of parent.children) {
                            let do_traversal = false;
                            let do_add = false;

                            for (const [_, overlap] of node.overlaps) {
                                switch (overlap) {
                                    case SOME_OVERLAP:
                                        do_traversal = true;
                                        break;
                                    case ALL_OVERLAP:
                                        do_add = true;
                                        break;
                                }
                            }

                            if (do_add) {
                                out.push(node.name + (node.is_leaf ? "" : "*"));
                            } else if (do_traversal) {
                                traverse(node);
                            }
                        }
                    };

                    let tree = {
                        test: test_nodes,
                        overlaps: new Map(), // map: span_id -> OVERLAP
                        children: new Map(), // map: index -> struct
                    };

                    gather_overlaps(tree, file, coverage_nodes, from, to);

                    traverse(tree);

                    return out;
                };

                let update_selection = (from, to) => {
                    if (from.line > to.line || (from.line == to.line && from.ch > to.ch)) {
                        let tmp = from;
                        from = to;
                        to = tmp;
                    }

                    let file = files[current.file];
                    let filtered = gather_tests(file, file.c, tests, from, to);
                    el_test_tree.innerHTML = "";
                    filtered.forEach(test_name => {
                        let element = document.createElement('p');
                        element.className = "test-name";
                        element.innerText = test_name;
                        el_test_tree.appendChild(element);
                    });
                };

                let load_source = (path) => {
                    if (!files[path]) { return; }

                    for (let i = 0; i < el_file_tree.childNodes.length; i++) {
                        let el = el_file_tree.childNodes[i];
                        if (el.path == path) {
                            el.classList.add("selected");
                        } else {
                            el.classList.remove("selected");
                        }
                    }
                    el_source.doc.setValue("// Loading... ");
                    fetch(`${path}`)
                        .then(response => response.text())
                        .then(source => {
                            el_source.doc.setValue(source);
                            current.file = path;
                            markup(files[path]);
                            if (pending.start_line) {
                                var start = {
                                    line: pending.start_line - 1,
                                    ch: pending.start_column ? pending.start_column - 1 : 0
                                };
                                var end = {
                                    line: pending.end_line ? pending.end_line - 1 : pending.start_line - 1,
                                    ch: pending.end_column ? pending.end_column - 1 : 0
                                };
                                el_source.doc.setSelection(start, end);
                                update_selection(start, end);
                            }
                            pending = {};
                        });
                };

                el_source.doc.on("beforeSelectionChange", (doc, selection) => {
                    if (!files[current.file]) { return; }

                    let range = selection.ranges[0];
                    let from = range.head;
                    let to = range.anchor;

                    set_location(current.file, from.line + 1, from.ch + 1, to.line + 1, to.ch + 1);

                    update_selection(from, to);
                });

                for (const path of Object.keys(files)) {
                    let file = files[path];

                    let div = document.createElement('div');
                    div.className = "file-div";
                    div.onclick = () => { pending = {}; load_source(path); }
                    div.path = path;
                    el_file_tree.appendChild(div);

                    let coverage = document.createElement('span');
                    coverage.className = "file-coverage";
                    if (file.p != undefined) {
                        let red = 1.0 - file.p;
                        let green = file.p;
                        let normalize = 1.0 / (red * red + green * green);
                        red *= normalize;
                        green *= normalize;
                        coverage.innerText = Math.round(file.p * 100);
                        coverage.style = "background-color: RGB(" + 255 * red + "," + 255 * green + ", 0" + ")";
                    } else {
                        coverage.innerText = "--";
                        coverage.style = "background-color: RGB(180,180,180)";
                    }
                    div.appendChild(coverage);

                    let filepath = document.createElement('span');
                    filepath.className = "file-path";
                    filepath.innerText = path;
                    div.appendChild(filepath);
                }

                if (pending.file) {
                    load_source(pending.file);
                }
            });
        };

    </script>
</body>

</html>
