/*
Copyright 2025 The Matrix.org Foundation C.I.C.

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

// Determine the current version as defined in hugo.toml. This will either be
// "unstable" or "vX.X" and doesn't depend on the current URL.
//
// The oddity below is an attempt at producing a readable Hugo template while
// avoiding JS syntax errors in your IDE.
const currentVersion = `{{ if eq .Site.Params.version.status "unstable" }}
    {{- /**/ -}}
    unstable
    {{- /**/ -}}
{{ else }}
    {{- /**/ -}}
    {{ printf "v%s.%s" .Site.Params.version.major .Site.Params.version.minor }}
    {{- /**/ -}}
{{ end }}`;

// Determine the current version segment by regex matching the URL. This will either
// be "unstable", "latest", "vX.X" (production) or undefined (local & netlify).
const href = window.location.href;
const segmentMatches = href.match(/(?<=\/)unstable|latest|v\d+.\d+(?=\/)/);
const currentSegment = segmentMatches ? segmentMatches[0] : undefined;

// Determine the selected menu element. If we were able to obtain the version
// segment from the URL (production), use that. Otherwise (local & netlify),
// fall back to the version as defined in Hugo.
const selected = currentSegment ?? currentVersion;

function appendVersion(parent, name, segment, url) {
    // The list item
    const li = document.createElement("li");
    if (segment === selected) {
        li.classList.add("version-picker-selected");
    }
    if (segment === "latest") {
        li.classList.add("version-picker-latest");
    }
    parent.appendChild(li);

    // The link
    const a = document.createElement("a");
    a.classList.add("dropdown-item");
    a.setAttribute("href", url);
    li.appendChild(a);

    // Handle clicks manually to preserve the current path / fragment
    a.addEventListener("click", (ev) => {
        // If the URL is a relative link (i.e. the historical versions changelog), just
        // let the browser load it
        if (url.startsWith("/")) {
            return;
        }

        // If we couldn't determine the current segment, we cannot safely replace
        // it and have to let the browser load the (root) URL instead
        if (!currentSegment) {
            return;
        }

        // Otherwise, stop further event handling and replace the segment
        ev.preventDefault();
        ev.stopPropagation();
        window.location.href = href.replace(`/${currentSegment}/`, `/${segment}/`);
    });

    // The link text
    const text = document.createTextNode(name);
    a.appendChild(text);
}

// If we're in the unstable version, we're the latest thing and can just load
// versions.json from our own resources. Otherwise, we fall back to loading it
// from /unstable/versions.json, assuming we are on the spec.matrix.org deployment.
const url = currentVersion === "unstable"
    ? '{{ .Site.Home.Permalink }}versions.json'
    : "/unstable/versions.json";

fetch(url)
    .then(r => r.json())
    .then(versions => {
        // Find the surrounding list element
        const ul = document.querySelector("ul#version-selector");
        if (!ul) {
            console.error("Cannot populate version selector: ul element not found");
            return;
        }

        // Add a entries for the unstable version and the "latest" shortcut
        appendVersion(ul, "unstable", "unstable", "https://spec.matrix.org/unstable");
        const latestName = versions?.length ? `latest (${versions[0].name})` : "latest";
        appendVersion(ul, latestName, "latest", "https://spec.matrix.org/latest");

        // Add an entry for each proper version
        for (const version of versions) {
            appendVersion(ul, version.name, version.name, `https://spec.matrix.org/${version.name}`);
        }

        // For historical versions, simply link to the changelog
        appendVersion(ul, "historical", "historical", '{{ (site.GetPage "changelog/historical").RelPermalink }}');
    });
