<!doctype html>
<!--
 Copyright 2022 The Dawn and Tint Authors

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

<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,
        });

        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>
