/*
 * Queue - A Queueing system that can be used to handle labs in higher education
 * Copyright (C) 2016-2024  Delft University of Technology
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
/**
 * Service worker file.
 *
 * NOTE: This file MUST be located in the root.
 */
"use strict";

// Setup caches for the service worker to serve to the browser
// TODO: Figure out what files are safe to cache, i.e. what files will nearly never be updated
const CACHE_NAME = "tudelft-queue-cache";
const URLS_TO_CACHE = [];

// Sets up caches at the moment of installing the service worker
self.addEventListener("install", event => {
    event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(URLS_TO_CACHE)));
});

// Responds to fetches done by the browser with cached items if possible
self.addEventListener("fetch", event => {
    event.respondWith(
        caches.match(event.request).then(response => {
            // Cache hit - return response
            if (response) {
                return response;
            }
            return fetch(event.request);
        })
    );
});

// Handle the event of a push message coming in
self.addEventListener("push", function (event) {
    const data = event.data.json();
    const title = data.title;
    const icon = data.icon != null ? data.icon : "/img/icon.png";
    const tag = data.tag != null ? data.tag : "notification";
    const body = data.body;

    return self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag,
        data: data,
        vibrate: [500, 100, 100],
    });
});

// Handle a notification being clicked by the user by redirecting them to the relevant page
self.addEventListener("notificationclick", function (event) {
    // Extract the url to go to
    const url = event.notification.data.url;

    // Android doesn't close the notification when you click on it (see: http://crbug.com/463146)
    event.notification.close();

    // This looks to see if the current is already open and focuses if it is
    event.waitUntil(
        self.clients
            .matchAll({
                type: "window",
            })
            .then(clientList => {
                // Loop through all clients and find the first one to focus on
                const found = clientList.some(client => {
                    if (client.url === url && "focus" in client) {
                        client.focus();
                        return true;
                    }
                    return false;
                });

                if (!found && "openWindow" in self.clients) {
                    return self.clients.openWindow(url);
                }
            })
    );
});
