<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <title>MIST Editor</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
    <style type="text/css" media="screen">
        #editor {
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 400px;
            border: 2px solid #808080;
            resize: vertical;
        }

        #resultsConsole {
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 250px;
            border: 2px solid #808080;
            resize: vertical;
        }
        .scroll {
            overflow: scroll;
            height: 354px;
            overflow-y: auto;
            scroll-behavior: smooth;
        }
    </style>
</head>
<body>

<div class="container">
    <div class="row">
        <div class="col">
            <div class="text-center">
                <img class="d-block mx-auto" src="https://raw.githubusercontent.com/BBVA/mist/master/images/logo-yellow-250x250.png" alt="" width="72" height="72">
                <p class="lead">Online editor for MIST</p>
            </div>

        </div>
        <div class="col-4 mt-4 mb-4 d-none d-lg-block">
            <h4><label for="serverBox" class="form-label text-muted">Server</label></h4>
            <input class="form-control" id="serverBox" type="text" value="Loading...">
        </div>
    </div>

    <div class="row">
        <div class="col">
            <div class="col">
                <div class="row justify-content-start">
                    <h2>Interactive IDE:</h2>
                    <div class="col" >
                        <div id="editor" class="rounded-lg"></div>
                        <div id="waiting" class="spinner-border" role="status" style="float: right; margin-top: 20px; margin-right: 20px; visibility: hidden;">
                            <span class="sr-only">Loading...</span>
                        </div>
                        <a id="execute" class="btn btn-success mt-2 my-2">Execute!</a><br>
                        <small>(Use <kbd> ctrl+Enter</kbd> as execution shortcut)</small>
                    </div>
                </div>
            </div>
            <div class="col my-4 mt-8">
                <h2>Output results</h2>
                <div id="resultsConsole" disabled class="rounded-lg"></div>
            </div>
        </div>
        <div class="col-4 d-none d-lg-block">
            <h4 class="d-flex justify-content-between align-items-center mb-3">
                <span class="text-muted">Language Basics</span>
                <span class="badge badge-secondary badge-pill">3</span>
            </h4>
            <div class="row">
                <div class="col scroll">
                    <ul class="list-group mb-3">

                        <!-- Print Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">print</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Print a text into screen</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>print "hello"</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#printExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="printExample">
                                                <code><pre>
data MyData {
    ip
}
print "hello"
print MyData.ip

}</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END Print Command -->

                        <!-- Exec Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">exec</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Execute a shell command</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>exec "bash -c ls {hidden} -1 {filter}" {...}</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#execExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="execExample">
                                                <code><pre>
exec "bash -c ls {hidden} -1 {filter}" {
    input {
        filter = "*"
        hidden = "-a"
    }
    output {
        result
        resultCode
        consoleOutput
        consoleError
    }
    then {
        print resultCode
    }
}</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END Exec Command -->

                        <!-- Put Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">put</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Put information into information bucket</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>put "hello" => myData</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#putExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="putExample">
                                                <code><pre>
data myHosts {
    Host
    Status
}

# ip is a variable form before executions
put ip 'Up' => myHosts
put ip 'Up' => myHosts(Host, Status)
put 'Up' => myHosts(Status)
</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END Put Command -->

                        <!-- searchInJSON Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">searchInJSON</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Search into JSON document by using JSON Path</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>searchInJSON "[JSON PATH QUERY]" myData.JSONtext {...}</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#searchInJsonExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="searchInJsonExample">
                                                <code><pre>

data myData {
    JSONtext
}

put '''
{
  "employees": [
    {
      "id": 1,
      "name": "Pankaj",
      "salary": "10000"
    },
    {
      "name": "David",
      "salary": "5000",
      "id": 2
    }
  ]
}
''' => myData

searchInJSON "employees[1].name" myData.JSONtext {
    output {
        result
        found
        value
    }
    then {
        print result
        print found
        print value
    }
}
</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END searchInJSON Command -->

                        <!-- searchInText Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">searchInText</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Search into Text by using Regex expression</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>searchInText "[REGEX]" myData.text {...}</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#searchInTextExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="searchInTextExample">
                                                <code><pre>
data myData {
    text
}

put "Hello, my name is Peter and I like Mist!" => myData

searchInText "Peter" myData.text {
    output {
        result
        found
    }
    then {
        check found is True {
            print "Peter found"
        }
    }
}
</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END searchInText Command -->

                        <!-- searchInXML Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">searchInXML</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Search into XML document by using XPath</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>searchInXML "[XPATH QUERY]" myData.XMLtext {...}</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#searchInXMLExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="searchInXMLExample">
                                                <code><pre>

data myData {
    XMLtext
}

put '''&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;bookstore&gt;
    &lt;book category=&quot;cooking&quot;&gt;
        &lt;title lang=&quot;en&quot;&gt;Everyday Italian&lt;/title&gt;
        &lt;author&gt;Giada De Laurentiis&lt;/author&gt;
        &lt;year&gt;2005&lt;/year&gt;
        &lt;price&gt;30.00&lt;/price&gt;
    &lt;/book&gt;
    &lt;book category=&quot;children&quot;&gt;
        &lt;title lang=&quot;en&quot;&gt;Harry Potter&lt;/title&gt;
        &lt;author&gt;J K. Rowling&lt;/author&gt;
        &lt;year&gt;2005&lt;/year&gt;
        &lt;price&gt;29.99&lt;/price&gt;
    &lt;/book&gt;
&lt;/bookstore&gt;
''' => myData

searchInXML "./book[2]/title" myData.XMLtext {
    output {
        result
        found
        value
    }
    then {
        print result
        print found
        print value
    }
}
</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END searchInXML Command -->

                         <!-- CSVPut Command -->
                         <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">CSVPut</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Find open ports at some specific host</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>CSVput "[FILE]" => [DATA STRUCTURE]</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#CSVPutExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="CSVPutExample">
                                                <code><pre>
data myHostsChecked {
    Host
    OpenPorts
}

CSVput "examples/myhosts.csv" => myHosts
</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END CSVPut Command -->

                        <!-- CSVdump Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div class="col-4">
                                            <h6 class="my-0">CSVdump</h6>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">Write a data structure of the knowledge base into a CSV file</span>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <code>CSVdump [DATA STRUCTURE] => "[FILE]"</code>
                                        </div>
                                    </div>
                                    <div class="row my-2">
                                        <div class="col">
                                            <button class="btn btn-sm btn-secondary" type="button" data-toggle="collapse" data-target="#CSVdumpExample" aria-expanded="false" aria-controls="collapseExample">Example &rarr;</button>
                                        </div>
                                    </div>
                                    <div class="row">
                                        <div class="col">
                                            <div class="collapse my-2" id="CSVdumpExample">
                                                <code><pre>
data myHostsChecked {
    Host
    OpenPorts
}

put "127.0.0.1" "21,22,8080" => myHostsChecked

CSVdump myHostsChecked => "myHostsChecked.csv"
</pre></code>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- END CSVdump Command -->

                    </ul>
                </div>
            </div>
            <hr class="hr my-4">
            <h4 class="d-flex justify-content-between align-items-center mb-3">
                <span class="text-muted">Commands Cheatsheet</span>
                <span class="badge badge-secondary badge-pill">3</span>
            </h4>
            <div class="row">
                <div class="col scroll">
                    <ul class="list-group mb-3">
                        {% for c in cheatsheet: %}
                        <!-- Begin Command -->
                        <li class="list-group-item d-flex justify-content-between lh-condensed">
                            <div class="row">
                                <div class="col">
                                    <div class="row">
                                        <div style="overflow: auto;" class="col-4">
                                            <h6 class="my-0">{{c.command}}</h6>
                                            <code>{{c.latest_version}}</code>
                                        </div>
                                        <div class="col-8">
                                            <span class="text-muted float-right">{{c.description}}</span>
                                        </div>
                                    </div>
                                    <!-- <div class="row">
                                        <div class="col">
                                            <code>{{c.latest_version}}</code>
                                        </div>
                                    </div> -->
                                    <div class="row my-2">
                                        <div class="col">
                                            <a href="{{c.uri}}/tree/master/{{c.command}}" class="btn btn-sm btn-secondary" role="button" target="_blank" >Open documentation page &rarr;</a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </li>
                        <!-- End Command -->
                        {% endfor %}
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

<script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js" integrity="sha384-oesi62hOLfzrys4LxRF63OJCXdXDipiYWBnvTl9Y9/TRlw5xlKIEHpNyvvDShgf/" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="mode-mist.js" type="text/javascript" charset="utf-8"></script>

<script>
    var editor = ace.edit("editor");
    editor.setTheme("ace/theme/monokai");
    editor.session.setMode("ace/mode/mist");
    editorHTML = document.getElementById('editor')
    editorHTML.style.fontSize='15px';

    var results = ace.edit("resultsConsole");
    results.setTheme("ace/theme/monokai");
    results.session.setMode("ace/mode/python");
    results.setReadOnly(true);
    resultsHTML = document.getElementById('resultsConsole')
    resultsHTML.style.fontSize='15px';

    lastEditorHeight = editorHTML.offsetHeight
    lastResustHeight = resultsHTML.offsetHeight
    function resizeCheck(last, current, ace) {
        if (last != current) {
            ace.resize(true)
        }
        return current
    }
    editorHTML.onmouseup = () => { lastEditorHeight = resizeCheck(lastEditorHeight, editorHTML.offsetHeight, editor)}
    editorHTML.onmousedown = () => { lastEditorHeight = resizeCheck(lastEditorHeight, editorHTML.offsetHeight, editor)}
    resultsHTML.onmouseup = () => { lastResustHeight = resizeCheck(lastResustHeight, resultsHTML.offsetHeight, results)}
    resultsHTML.onmousedown = () => { lastResustHeight = resizeCheck(lastResustHeight, resultsHTML.offsetHeight, results)}

    const btn = document.getElementById("execute");
    const waiting = document.getElementById("waiting");
    const server = document.getElementById("serverBox");

    server.value = window.location.origin

    function waitForResults (fn, jobId) {
      return new Promise((resolve) => {
        setTimeout(() => resolve(fn(jobId)), 1000)
      })
    }

    async function launchJob() {

        const run = await fetch(
            server.value + "/run",
            {
                method: "POST",
                body: JSON.stringify({content: editor.getValue()}),
                cache: 'no-cache',
                headers: {
                  'Content-Type': 'application/json'
                }
            }
        );

        const jsonRunResponse = await run.json();

        return jsonRunResponse.jobId;
    }
    async function checkStatus(jobId) {
        const status = await fetch(
            `${server.value}/run/${jobId}`,
            {
                method: "GET",
                cache: 'no-cache',
            }
        );

        const jsonRunResponse = await status.json();

        return jsonRunResponse.message;
    }

    var jobId = null
    var source = null

    function getRealTime(jobid) {
        source = new EventSource(server.value + "/stream?channel=" + jobid);
        source.addEventListener("message", function(event) {
            //console.log(event)
            var data = JSON.parse(event.data);
            results.setValue(results.getValue() + data.message)
            results.scrollPageDown()
        }, false);
        source.addEventListener('error', function(event) {
            console.log("Failed to connect to event stream");
        }, false);
    }

    async function runAsync() {
        jobId = await launchJob();

        if (jobId === null) {
            return "Error launching job"
        }

        getRealTime(jobId)

        var output = "job already running"
        while (output == "job already running") {
            console.log("wait for results")
            if (btn.innerText == "Execute!") return "Job cancelled"
            output = await waitForResults(checkStatus, jobId)
        }
        return output
    }

    function showExecute() {
        btn.innerText = "Execute!"
        waiting.style.visibility = "hidden"
    }

    function showCancel() {
        btn.innerText = "Cancel"
        waiting.style.visibility = "visible"
    }

    function runCode() {
        results.setValue("")
        if (btn.innerText == "Execute!") {
            showCancel()
            runAsync().then((output) => {
                console.log("Execution finished");
                source.close()
                results.setValue(output.error ? output.error : output);
            }).catch(err => {
                console.log(err);
            }).finally( () => showExecute());
        }
        else { // Cancel
            showExecute()
            console.log("TODO cancel job", jobId)
        }
    }

    btn.addEventListener("click", function (event) {
        runCode();
    })

    document.addEventListener('keydown', function(event) {
        if (event.ctrlKey && event.keyCode === 13) {
            event.preventDefault();
            runCode();
        }
    });

</script>
</body>
</html>
