<div id="compassPage" x-data="alpineCompass()">
    <div>
        <div x-data="{showText: false}">
            <h2 x-on:mouseover="showText = true" x-on:mouseleave="showText = false">Compass<sub x-show="showText" class="is-size-7 pl-1">find your way</sub></h2>
        </div>
        <p>Generate a layer file for any adversary, which you can overlay on the matrix below
            <b>OR</b> Create an adversary in the matrix, then
            upload the layer file to generate an adversary to use in an operation</p>
    </div>
    <hr>
    <div>
        <div class="is-flex is-flex-direction-row mb-4">
            <div class="is-flex is-flex-direction-column">
                <label for="layer-selection-adversary" class="pb-2 is-size-6">Generate Layer</label>
                <div class="is-flex is-flex-direction-row">
                    <div class="field has-addons">
                    <div class="control">
                        <div id="layerSelectionAdversary" class="select is-small">
                            <select id="layer-selection-adversary" x-model="selectedAdversaryID">
                                <option value="" selected>Select an Adversary (All)</option>
                                {% for adv in adversaries %}
                                <option value="{{ adv.adversary_id }}">{{ adv.name }}</option>
                                {% endfor %}}
                            </select>
                        </div>
                    </div>
                    <div class="control">
                    <label for="generateLayer">
                        <button id="generateLayer" class="button is-primary is-small"
                                x-on:click="generateLayer()"><i class="pr-1 fas fa-download"></i>
                            <span class="has-tooltip-multiline has-tooltip-bottom"
                                  data-tooltip="In the Navigator, select 'Open Existing Layer' -> 'Upload from local' -> and upload the generated layer file.">Generate Layer
                            </span>
                        </button>
                    </label>
                    </div>
                    </div>
                </div>
            </div>
            <div class="is-flex is-flex-direction-column ml-6">
                <label class="pb-2 is-size-6">Generate Adversary</label>
                <div class="is-flex is-flex-direction-row">
                    <input id="generateAdversary" type="file" x-on:change="uploadAdversaryLayer($event.target)" hidden/>
                    <button for="generateAdversary" class="button is-primary is-small"><i class="pr-1 fas fa-upload"></i>
                        <span class="has-tooltip-multiline has-tooltip-bottom"
                              data-tooltip="Select techniques in the ATT&CK matrix below -> download the layer as json -> then upload the Adversary layer file here. You can now use the Adversary profile in Caldera, under the name given the layer file.">
                                <label for="generateAdversary">
                                    Create Operation
                                </label>
                            </span>
                    </button>
                    <input id='adversaryLayerInput' type='file' hidden/>
                </div>
            </div>
        </div>
    </div>
    <div>
        <iframe src="https://mitre-attack.github.io/attack-navigator/enterprise/" class="frame">
        </iframe>
    </div>

    <template x-if="openModal">
        <div class="modal is-active">
            <div class="modal-background" @click="openModal = false"></div>
            <div class="modal-card">
                <header class="modal-card-head">
                    <p class="modal-card-title">Adversary Created</p>
                    <h3 x-text="adversaryCreated.name"></h3>
                    <h3 x-text="adversaryCreated.response"></h3>
                </header>
                <section class="modal-card-body">
                    <div>
                        <table class="table is-striped">
                            <thead>
                            <tr>
                                <th id="missing-abilities-tactic" class="has-text-grey">Tactic</th>
                                <th id="missing-abilities-technique" class="has-text-grey">Technique ID</th>
                            </tr>
                            </thead>
                            <tbody id="missing-abilities-body">
                            <template x-for="(item, index) in adversaryCreated.unmatched_techniques" :key="index">
                            <tr>
                                <td x-text="item.tactic"></td>
                                <td x-text="item.technique_id"></td>
                            </tr>
                            </template>
                            </tbody>
                        </table>
                        <p class="has-text-centered">An adversary is only as good as its abilities. APT layers will
                            cover the same tactics and techniques. Procedures that accurately represent an APT only
                            come from proper curation of an adversary.</p>
                    </div>
                </section>
                <footer class="modal-card-foot">
                    <nav class="level">
                        <div class="level-left">
                        </div>
                        <div class="level-right">
                            <div class="level-item">
                                <button class="button is-small" @click="openModal = false">Close</button>
                            </div>
                        </div>
                    </nav>
                </footer>
            </div>
        </div>
    </template>
</div>

<script>
    function alpineCompass() {
        return {
            openModal: false,
            selectedAdversaryID: '',
            adversaryCreated: {
                name: '',
                response: '',
                unmatched_techniques: []
            },

            generateLayer() {
                function downloadObjectAsJson(data) {
                    let exportName = 'layer';
                    let dataStr = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(data, null, 2))}`;
                    let downloadAnchorNode = document.createElement('a');
                    downloadAnchorNode.setAttribute('href', dataStr);
                    downloadAnchorNode.setAttribute('download', `${exportName}.json`);
                    document.body.appendChild(downloadAnchorNode); // required for firefox
                    downloadAnchorNode.click();
                    downloadAnchorNode.remove();
                }

                const postData = this.selectedAdversaryID ? {
                    index: 'adversary',
                    adversary_id: this.selectedAdversaryID
                } : { index: 'all' };
                restRequest('POST', postData, downloadObjectAsJson, '/plugin/compass/layer');
            },

            uploadAdversaryLayer(e) {
                if (!e || !e.files || !e.files[0].name) toast('Error loading layer file', false);

                let formData = new FormData();
                formData.append('file', e.files[0]);
                fetch('/plugin/compass/adversary', {
                    method: 'POST',
                    body: formData
                })
                    .then((response) => response.json())
                    .then((data) => {
                        this.adversaryCreated = {
                            name: data.name,
                            response: data.description,
                            unmatched_techniques: data.unmatched_techniques.map((item) => { return { technique_id: item.technique_id, tactic: item.tactic }; })
                        };
                        this.openModal = true;
                    })
                    .catch((error) => {
                        toast('Error uploading adversary layer', false);
                    });
            }
        };
    }
</script>
<style>
    #compassPage .frame {
        display: flex;
        width: 100%;
        border-radius: 5px;
        overflow: auto;
        height: 900px;
        border: 2px solid #666666;
    }
</style>
