// ==UserScript==
// @name           Simple URL Tracker Cleaner
// @namespace      https://github.com/StaticPH
// @match          *://*/*
// @version        1.6.2
// @createdAt      8/10/2021
// @author         StaticPH
// @description    Scrub various common tracker parameters from URLs.
// @license        MIT
// @updateURL      https://raw.githubusercontent.com/StaticPH/Userscripts/master/simple_url_tracker_cleaner.user.js
// @downloadURL    https://raw.githubusercontent.com/StaticPH/Userscripts/master/simple_url_tracker_cleaner.user.js
// @homepageURL    https://github.com/StaticPH/UserScripts
// @supportURL     https://github.com/StaticPH/UserScripts/issues
// @icon           https://cdn-icons-png.flaticon.com/32/185/185441.png
// @grant          none
// @run-at         document-end
// ==/UserScript==
// Icon from https://www.flaticon.com/free-icon/fly-swatter_185441; All rights belong to their original owner(s).

(function(){
	'use strict';

	function queryParamFirst(href){
		// Put the damn query parameter first so it's predictable
		const args = href.split('&');
		const queryIndex = args.findIndex(s => s.startsWith('q='));
		args[0] = args[0].replace('search?', `search?${args[queryIndex]}&`);
		delete args[queryIndex];
		return args.filter(s => s).join('&');
	}

	async function cleanURLs(){
		Array.from(document.links).forEach(async function(link){
			let fixed = null;
			if (link.href.match(/google\.[^/]+\/url\?.*/)){
				const url = new URL(link.href);
				if (url.searchParams.has('url')){
					fixed = url.searchParams.get('url');
					if (!fixed || fixed.length === 0){ console.warn('Found empty "url" parameter in link: ' + link.href); }
					else{
						console.log( link.href + ' --> ' + fixed );
						link.href = fixed;
					}
				}
				else if (url.searchParams.has('q')){
					fixed = url.searchParams.get('q');
					if (!fixed || fixed.length === 0){ console.warn('Found empty "q" parameter in link: ' + link.href); }
					else if (fixed.startsWith('https://')){
						if (url.searchParams.has('tbs')){ // This is one of the parameters actually worth keeping, as it controls some of the "advanced" filtering
							fixed = fixed + '&' + url.searchParams.get('tbs');
						}
						console.log( link.href + ' --> ' + fixed );
						link.href = fixed;
					}
					else{
						console.info('Expected query parameter starting with "https://", but found q=' + fixed);
					}
				}
				else{
					console.warn('Could not find expected "url" or "q" parameter for link: ' + link.href);
				}
			}
			if (link.href.match(/(?:[?&])(amp;)?(utm_(source|medium|campaign|term|content)|(fb|g)clid)=[^&?#]*[&?#]?/)){
				fixed = link.href.replace(/(?:[?&])(amp;)?(utm_(source|medium|campaign|term|content)|(fb|g)clid)=[^&?#]*/g, '').replace(/[?&]*#/, '#').replace(/[?&]*$/, '');
				console.log( link.href + ' --> ' + fixed );
				link.href = fixed;
			}
			// if (link.href.match(/google\.[^/]+\/search\?q=.+/)){
			if (link.href.match(/google\.[^/]+\/search.*?[&?](ei|sa|ved|bi[wh]|spell|oq|gs_lcp|sclient|uact)=[^&?#]*/)){
				// fixed = link.href.replace(/&(ei|sa|ved|bi[wh]|spell|oq|gs_lcp|sclient|uact)=[^&?#]*/g, '');
				// fixed = link.href.replace(/\?([^&#=]+=[^&#]*((&[^&#=]+=[^&#]*)+)?&)(q=[^&?#]*)(.*)/, '?$4&$1$5').replace('&&','&'); // This *CAN'T* be the optimal way to handle scenarios where 'q' isn't the first search parameter...
				fixed = queryParamFirst(link.href);
				fixed = fixed.replace(/&(ei|sa|ved|bi[wh]|spell|oq|gs_lcp|sclient|uact)=[^&?#]*/g, '');
				/* Compare performance against:
				const oldUrl = new URL(link.href);
				['ei','sa','ved','biw','bih','spell','oq','gs_lcp','sclient','uact'].forEach(oldUrl.searchParams.delete);
				fixed = oldUrl.href;
				*/
				console.log( link.href + ' --> ' + fixed );
				link.href = fixed;
			}
			// TODO: AMAZON URLS
			// On Amazon product pages in particular, you can remove keywords, ref, dchild, pd*, pf*, qid, and sr
			if (link.href.match(/amazon\.[^/]+\/[^/]+\/dp\/[^/]+\/[^?&]+[?&]/)){
				fixed = link.href.replace(/[&?].+$/, '');
				console.log( link.href + ' --> ' + fixed );
				link.href = fixed;
			}
		});
		return;
	}

	cleanURLs();
	setInterval(cleanURLs, 5000);
	// Apparently calling `cleanURLs()` in the setInterval call violates CSP on google pages, because something decides to try interpreting a simple string as javascript.

})();