let app_v = '2024.0601';

/**
 Service worker handler
 **/

// Prepare caches
const swCaches = {
    'static': 'cedar_static_' + app_v ,
    'dynamic': 'cedar_dynamic_' + app_v ,
    'icons': 'cedar_icons_' + app_v
};

// Offline page location
const swOffline = 'Static/offline.html' ;
const sw404     = 'Static/404.html' ;

// Load workbox
importScripts( 'https://storage.googleapis.com/workbox-cdn/releases/3.2.0/workbox-sw.js' );

if ( workbox ) {

    // Cache names setup
    workbox.core.setCacheNameDetails({
        prefix: 'cedar',
        suffix: app_v
    }) ;

    // Pre-cache paths
    // Load this up with all ststic resources that may be called on by an offline page load
    // This should include icons etc. that are needed for hover-on effects that may not have been
    // cached before going off-line.  This list need not include icons that will definitely have been
    // cached by an online visit, such as the CEDAR logo.
    const precacheList = [
        {url: '/favicon.ico' , revision: app_v },
        {url: '/Static/manifest.json', revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-shield-alert.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-network-disconnect.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-connection-quality-veryhigh.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-draw-pen-add.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-draw-pen-add-green.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-tools.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-tools-green.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-home-empty.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-home-empty-green.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-door-leave.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-door-leave-green.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-magnify-green.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-arrow-right.png' , revision: app_v },
        {url: '/Static/Images/ops_page/ajax-loader_search.gif' , revision: app_v },
        {url: '/Static/Images/ops_page/ajax-loader_search_alt.gif' , revision: app_v },
        {url: '/Static/Images/ops_page/ajax-loader_large_dial.gif' , revision: app_v },
        {url: '/Static/CSS/ops_auth.css' , revision: app_v },
        {url: '/Static/Compiled/sprite.png' , revision: app_v },
        {url: '/Static/Compiled/sprite.css' , revision: app_v },

        // Offline page resources
        {url: '/Static/offline.html' , revision: app_v },
        {url: '/Static/Lib/jQuery/jquery-3.6.1.min.js' , revision: app_v },
        {url: '/Static/Lib/jQuery/jquery-migrate-3.4.1.min.js' , revision: app_v },
        {url: '/Static/Lib/jQuery/plugins/jquery.easing.1.4.2.min.js' , revision: app_v },
        {url: '/Static/CSS/ops_animations.css' , revision: app_v },
        {url: '/Static/CSS/ops_page.css' , revision: app_v },
        {url: '/Static/CSS/ops_migrate.css' , revision: app_v },
        {url: '/Static/Compiled/cedar.auth.min.css' , revision: app_v },
        {url: '/Static/Compiled/cedar.auth.min.js' , revision: app_v },
        {url: '/Static/Compiled/cedar.min.css' , revision: app_v },
        {url: '/Static/Compiled/cedar.min.js' , revision: app_v },
        {url: '/Static/Lib/ops_jQ/ops_offline.js' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-check.png' , revision: app_v },
        {url: '/Static/Icons/ui/ux2/appbar-alert.png' , revision: app_v },
        {url: '/Static/Images/App/CEDAR_logo_large_white.png' , revision: app_v } ,
        {url: '/Static/Images/App/CEDAR_logo_bg_white.png' , revision: app_v }
    ] ;

    // Use the precache list to prepare resources before service-worker install
    workbox.precaching.precacheAndRoute(
        precacheList ,
        {
            directoryIndex: null,
            cleanUrls: false
        }
    ) ;

    // Google fonts: Prioritise cache, no max, no expiry
    workbox.routing.registerRoute(
        new RegExp('https:\/\/fonts.(?:googleapis|gstatic).com/(.*)'),
        workbox.strategies.cacheFirst({
            cacheName: swCaches.static
        })
    );

    // Google visualisations and more: network first, timeout after 1 second
    // Note: this may not actually cache anything with opaque responses.
    workbox.routing.registerRoute(
        new RegExp('https://www.(?:googleapis|gstatic).com\/(.*)'),
        workbox.strategies.networkFirst({
            networkTimeoutSeconds: 1,
            cacheName: swCaches.static,
            plugins: [
                new workbox.expiration.Plugin({
                    // 50 maximum entries
                    maxEntries: 200,
                    // Cache for a maximum of 30 days
                    maxAgeSeconds: 30 * 24 * 60 * 60
                }),
            ],
        }),
    );

    // All CSS & JS: Prioritise cache but update in the background, expire after 30 days
    workbox.routing.registerRoute(
        new RegExp('\/.*(?:js|css)$'),
        workbox.strategies.staleWhileRevalidate({
            cacheName: swCaches.static,
            plugins: [
                new workbox.expiration.Plugin({
                    // No maximum file count
                    // Cache for a maximum of 30 days
                    maxAgeSeconds: 30 * 24 * 60 * 60
                })
            ],
        })
    );

    // Audio: Prioritise cache, no maximum age or limit
    workbox.routing.registerRoute(
        new RegExp('.*\\/[Ss]tatic\\/[Aa]udio\\/.*\\..*'),
        workbox.strategies.cacheFirst({
            cacheName: swCaches.static
        })
    );

    // Icons: Prioritise cache, no maximum age or limit (small footprint)
    workbox.routing.registerRoute(
        new RegExp('.*\\/[Ss]tatic\\/[Ii]cons\\/.*\\.(?:png|jpg|jpeg|svg|gif)'),
        workbox.strategies.cacheFirst({
            cacheName: swCaches.icons
        })
    );

    // Static Images: Prioritise cache, no maximum age but limit to 35
    workbox.routing.registerRoute(
        new RegExp('.*\\/[Ss]tatic\\/[Ii]mages\\/.*\\.(?:png|jpg|jpeg|svg|gif)'),
        workbox.strategies.cacheFirst({
            cacheName: swCaches.static,
            plugins: [
                new workbox.expiration.Plugin({
                    // No maximum file count
                    maxEntries: 35
                })
            ],
        })
    );

    // All other images: Prioritise cache, no maximum age but limit to 50
	workbox.routing.registerRoute(
		new RegExp('.*\\/public\/.*'),
		new workbox.strategies.NetworkOnly()
	);
    workbox.routing.registerRoute(
        new RegExp('.*\\.(?:png|jpg|jpeg|svg|gif)'),
        workbox.strategies.cacheFirst({
            cacheName: swCaches.static,
            plugins: [
                new workbox.expiration.Plugin({
                    // No maximum file count
                    maxEntries: 200
                })
            ],
        })
    );

	workbox.routing.registerRoute(
		new RegExp('.*\\/reports\/browse\/.*'),
		new workbox.strategies.NetworkOnly()
	);
	workbox.routing.registerRoute(
		new RegExp('.*\\/sso\/.*'),
		new workbox.strategies.NetworkOnly()
	);
	workbox.routing.registerRoute(
		new RegExp('.*\\/auth\/.*'),
		new workbox.strategies.NetworkOnly()
	);
	workbox.routing.registerRoute(
		new RegExp('.*\\/public\/.*'),
		new workbox.strategies.NetworkOnly()
	);

	// Person photos: Prioritise cache, but update in the background.

    const bgSyncPlugin = new workbox.backgroundSync.Plugin( swCaches.dynamic, {
        maxRetentionTime: 24 * 60 // Retry for max of 24 Hours
    });

    // Everything else: Wait 30 seconds to fall back on the cache
    const pageHandler = workbox.strategies.networkFirst({
        cacheName: swCaches.dynamic,
        networkTimeoutSeconds: 30,
        plugins: [
            new workbox.expiration.Plugin({
                // Cache for a maximum of 7 days
                maxAgeSeconds: 7 * 24 * 60 * 60
            }),
            bgSyncPlugin
        ]
    }) ;

    // The handle method returns a promise - we can check the response
    // and serve back the offline.html page.  This is Google's recommended
    // way of achieving custom offline/404 pages via workbox
    // The Reg Exp matches on any http[s]://xxx/yyy URL.  Root URL is not cached.
    workbox.routing.registerRoute(
        new RegExp('^(http|https)\\:\\/\\/.*$'), args => {  // change from '\/.*'
            return pageHandler.handle( args )
                .then( response => {
                    if( !response ) {
                        return caches.match( swOffline );
                    } // else if ( response.status === 404 ) {
                      //  return caches.match( sw404 ) ;
                    //}
                    return response ;
                });
        }
    );
}
