<div id="package-info-modal" tabindex="-1" role="dialog" class="modal fade">
    <div class="modal-dialog modal-xl" role="document">
        <div class="modal-content">
            <div id="package-info-modal-header" class="modal-header">
                <h4 id="package-info" class="modal-title"></h4>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
            </div>
            <div class="modal-body">
                <div class="form-group row mt-2">
                    <div class="col-4 col-lg-1" style="text-align: right">version</div>
                    <div id="package-info-version" class="col-8 col-lg-5"></div>
                    <div class="col-4 col-lg-1" style="text-align: right">packager</div>
                    <div id="package-info-packager" class="col-8 col-lg-5"></div>
                </div>

                <div class="form-group row mt-2">
                    <div class="col-4 col-lg-1" style="text-align: right">groups</div>
                    <div id="package-info-groups" class="col-8 col-lg-5"></div>
                    <div class="col-4 col-lg-1" style="text-align: right">licenses</div>
                    <div id="package-info-licenses" class="col-8 col-lg-5"></div>
                </div>

                <div class="form-group row mt-2">
                    <div class="col-4 col-lg-1" style="text-align: right">upstream</div>
                    <div id="package-info-upstream-url" class="col-8 col-lg-5"></div>
                    <div class="col-4 col-lg-1" style="text-align: right">AUR</div>
                    <div id="package-info-aur-url" class="col-8 col-lg-5"></div>
                </div>

                <div class="form-group row mt-2">
                    <div class="col-4 col-lg-1" style="text-align: right">packages</div>
                    <div id="package-info-packages" class="col-8 col-lg-5"></div>
                    <div class="col-4 col-lg-1" style="text-align: right">depends</div>
                    <div id="package-info-depends" class="col-8 col-lg-5"></div>
                </div>

                <hr class="col-12">

                <div id="package-info-variables-block" hidden>
                    <h3>Environment variables</h3>
                    <div id="package-info-variables-div" class="form-group row"></div>

                    <hr class="col-12">
                </div>

                <nav>
                    <div class="nav nav-tabs" role="tablist">
                        <button id="package-info-logs-button" class="nav-link active" data-bs-toggle="tab" data-bs-target="#package-info-logs" type="button" role="tab" aria-controls="package-info-logs" aria-selected="true"><h3>Build logs</h3></button>
                        <button id="package-info-changes-button" class="nav-link" data-bs-toggle="tab" data-bs-target="#package-info-changes" type="button" role="tab" aria-controls="package-info-changes" aria-selected="false"><h3>Changes</h3></button>
                    </div>
                </nav>
                <div class="tab-content" id="nav-tabContent">
                    <div id="package-info-logs" class="tab-pane fade show active" role="tabpanel" aria-labelledby="package-info-logs-button" tabindex="0">
                        <pre class="language-console"><code id="package-info-logs-input" class="pre-scrollable language-console"></code><button id="package-info-logs-copy-button" type="button" class="btn language-console" onclick="copyLogs()"><i class="bi bi-clipboard"></i> copy</button></pre>
                    </div>
                    <div id="package-info-changes" class="tab-pane fade" role="tabpanel" aria-labelledby="package-info-changes-button" tabindex="0">
                        <pre class="language-diff"><code id="package-info-changes-input" class="pre-scrollable language-diff"></code><button id="package-info-changes-copy-button" type="button" class="btn language-diff" onclick="copyChanges()"><i class="bi bi-clipboard"></i> copy</button></pre>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button id="package-info-update-button" type="submit" class="btn btn-success" onclick="packageInfoUpdate()" data-bs-dismiss="modal" hidden><i class="bi bi-play"></i><span class="d-none d-sm-inline"> update</span></button>
                <button id="package-info-remove-button" type="submit" class="btn btn-danger" onclick="packageInfoRemove()" data-bs-dismiss="modal" hidden><i class="bi bi-trash"></i><span class="d-none d-sm-inline"> remove</span></button>
                <button type="button" class="btn btn-secondary" onclick="showPackageInfo()"><i class="bi bi-arrow-clockwise"></i><span class="d-none d-sm-inline"> reload</span></button>
                <button type="button" class="btn btn-primary" data-bs-dismiss="modal"><i class="bi bi-x"></i><span class="d-none d-sm-inline"> close</span></button>
            </div>
        </div>
    </div>
</div>

<script>
    const packageInfoModal = $("#package-info-modal");
    const packageInfoModalHeader = $("#package-info-modal-header");
    const packageInfo = $("#package-info");

    const packageInfoLogsInput = $("#package-info-logs-input");
    const packageInfoLogsCopyButton = $("#package-info-logs-copy-button");

    const packageInfoChangesInput = $("#package-info-changes-input");
    const packageInfoChangesCopyButton = $("#package-info-changes-copy-button");

    const packageInfoAurUrl = $("#package-info-aur-url");
    const packageInfoDepends = $("#package-info-depends");
    const packageInfoGroups = $("#package-info-groups");
    const packageInfoLicenses = $("#package-info-licenses");
    const packageInfoPackager = $("#package-info-packager");
    const packageInfoPackages = $("#package-info-packages");
    const packageInfoUpstreamUrl = $("#package-info-upstream-url");
    const packageInfoVersion = $("#package-info-version");

    const packageInfoVariablesBlock = $("#package-info-variables-block");
    const packageInfoVariablesDiv = $("#package-info-variables-div");

    async function copyChanges() {
        const changes = packageInfoChangesInput.text();
        await copyToClipboard(changes, packageInfoChangesCopyButton);
    }

    async function copyLogs() {
        const logs = packageInfoLogsInput.text();
        await copyToClipboard(logs, packageInfoLogsCopyButton);
    }

    function hideInfoControls(hidden) {
        packageInfoRemoveButton.attr("hidden", hidden);
        packageInfoUpdateButton.attr("hidden", hidden);
    }

    function insertVariable(packageBase, variable) {
        const variableInput = document.createElement("div");
        variableInput.classList.add("input-group");

        const variableNameInput = document.createElement("input");
        variableNameInput.classList.add("form-control");
        variableNameInput.readOnly = true;
        variableNameInput.value = variable.key;

        const variableSeparator = document.createElement("span");
        variableSeparator.classList.add("input-group-text")
        variableSeparator.textContent = "=";

        const variableValueInput = document.createElement("input");
        variableValueInput.classList.add("form-control");
        variableValueInput.readOnly = true;
        variableValueInput.value = variable.value;

        const variableButtonRemove = document.createElement("button");
        variableButtonRemove.type = "button";
        variableButtonRemove.classList.add("btn");
        variableButtonRemove.classList.add("btn-outline-danger");
        variableButtonRemove.innerHTML = "<i class=\"bi bi-trash\"></i>";
        variableButtonRemove.onclick = _ => {
            $.ajax({
                url: `/api/v1/packages/${packageBase}/patches/${variable.key}`,
                type: "DELETE",
                dataType: "json",
                success: _ => variableInput.remove(),
            });
        };

        // bring them together
        variableInput.appendChild(variableNameInput);
        variableInput.appendChild(variableSeparator);
        variableInput.appendChild(variableValueInput);
        variableInput.appendChild(variableButtonRemove);

        packageInfoVariablesDiv.append(variableInput);
    }

    function loadChanges(packageBase, onFailure) {
        $.ajax({
            url: `/api/v1/packages/${packageBase}/changes`,
            data: {
                architecture: repository.architecture,
                repository: repository.repository,
            },
            type: "GET",
            dataType: "json",
            success: response => {
                const changes = response.changes;
                packageInfoChangesInput.text(changes || "");
                packageInfoChangesInput.map((_, el) => hljs.highlightElement(el));
            },
            error: onFailure,
        });
    }

    function loadLogs(packageBase, onFailure) {
        $.ajax({
            url: `/api/v2/packages/${packageBase}/logs`,
            data: {
                architecture: repository.architecture,
                repository: repository.repository,
            },
            type: "GET",
            dataType: "json",
            success: response => {
                const logs = response.map(log_record => {
                    return `[${new Date(1000 * log_record.created).toISOString()}] ${log_record.message}`;
                });
                packageInfoLogsInput.text(logs.join("\n"));
                packageInfoLogsInput.map((_, el) => hljs.highlightElement(el));
            },
            error: onFailure,
        });
    }

    function loadPackage(packageBase, onFailure) {
        const headerClass = status => {
            if (status === "pending") return ["bg-warning"];
            if (status === "building") return ["bg-warning"];
            if (status === "failed") return ["bg-danger", "text-white"];
            if (status === "success") return ["bg-success", "text-white"];
            return ["bg-secondary", "text-white"];
        };

        $.ajax({
            url: `/api/v1/packages/${packageBase}`,
            data: {
                architecture: repository.architecture,
                repository: repository.repository,
            },
            type: "GET",
            dataType: "json",
            success: response => {
                const description = response.find(Boolean);
                const packages = Object.keys(description.package.packages);
                const aurUrl = description.package.remote.web_url;
                const upstreamUrls = Array.from(
                    new Set(
                        Object.values(description.package.packages)
                            .map(single => single.url)
                    )
                ).sort();

                packageInfo.text(`${description.package.base} ${description.status.status} at ${new Date(1000 * description.status.timestamp).toISOStringShort()}`);

                packageInfoModalHeader.removeClass();
                packageInfoModalHeader.addClass("modal-header");
                headerClass(description.status.status).forEach(clz => packageInfoModalHeader.addClass(clz));

                packageInfoAurUrl.html(aurUrl ? safeLink(aurUrl, aurUrl, "AUR link").outerHTML : "");
                packageInfoDepends.html(listToTable(
                    Object.values(description.package.packages)
                        .reduce((accumulator, currentValue) => {
                            return accumulator.concat(currentValue.depends.filter(v => packages.indexOf(v) === -1))
                                .concat(currentValue.make_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (make)`))
                                .concat(currentValue.opt_depends.filter(v => packages.indexOf(v) === -1).map(v => `${v} (optional)`));
                        }, [])
                ));
                packageInfoGroups.html(listToTable(extractListProperties(description.package, "groups")));
                packageInfoLicenses.html(listToTable(extractListProperties(description.package, "licenses")));
                packageInfoPackager.text(description.package.packager);
                packageInfoPackages.html(listToTable(packages));
                packageInfoUpstreamUrl.html(upstreamUrls.map(url => safeLink(url, url, "upstream link").outerHTML).join("<br>"));
                packageInfoVersion.text(description.package.version);

                hideInfoControls(false);
            },
            error: (jqXHR, _, errorThrown) => {
                hideInfoControls(true);
                onFailure(jqXHR, null, errorThrown);
            },
        });
    }

    function loadPatches(packageBase, onFailure) {
        $.ajax({
            url: `/api/v1/packages/${packageBase}/patches`,
            type: "GET",
            dataType: "json",
            success: response => {
                packageInfoVariablesDiv.empty();
                response.map(patch => insertVariable(packageBase, patch));
                packageInfoVariablesBlock.attr("hidden", response.length === 0);
            },
            error: onFailure,
        });
    }

    function packageInfoRemove() {
        const packageBase = packageInfoModal.data("package");
        if (packageBase) return packagesRemove([packageBase]);
    }

    function packageInfoUpdate() {
        const packageBase = packageInfoModal.data("package");
        if (packageBase) return packagesAdd(packageBase, [], repository);
    }

    function showPackageInfo(packageBase) {
        const isPackageBaseSet = packageBase !== undefined;
        if (isPackageBaseSet)
            packageInfoModal.data("package", packageBase); // set package base as currently used
        else
            packageBase = packageInfoModal.data("package"); // read package base from the current window attribute

        const onFailure = (jqXHR, _, errorThrown) => {
            if (isPackageBaseSet) {
                const message = error => `Could not load package ${packageBase} info: ${error}`;
                showFailure("Load failure", message, jqXHR, errorThrown);
            }
        };

        loadPackage(packageBase, onFailure);
        loadPatches(packageBase, onFailure);
        loadLogs(packageBase, onFailure);
        loadChanges(packageBase, onFailure)

        if (isPackageBaseSet) packageInfoModal.modal("show");
    }

    $(_ => {
        packageInfoModal.on("hidden.bs.modal", _ => {
            packageInfoAurUrl.empty();
            packageInfoDepends.empty();
            packageInfoGroups.empty();
            packageInfoLicenses.empty();
            packageInfoPackager.empty();
            packageInfoPackages.empty();
            packageInfoUpstreamUrl.empty();
            packageInfoVersion.empty();

            packageInfoVariablesBlock.attr("hidden", true);
            packageInfoVariablesDiv.empty();

            packageInfoLogsInput.empty();
            packageInfoChangesInput.empty();

            packageInfoModal.trigger("reset");

            hideInfoControls(true);
        });
    });
</script>
