// ==UserScript==
// @name             Github Repo Network Tab
// @namespace        https://github.com/StaticPH
// @match            https://github.com/*/*
// @exclude-match    https://github.com/*/*/search*
// @exclude-match    https://github.com/about*
// @exclude-match    https://github.com/contact*
// @exclude-match    https://github.com/customer-stories*
// @exclude-match    https://github.com/enterprise*
// @exclude-match    https://github.com/explore*
// @exclude-match    https://github.com/features*
// @exclude-match    https://github.com/login/*
// @exclude-match    https://github.com/marketplace*
// @exclude-match    https://github.com/new*
// @exclude-match    https://github.com/notifications*
// @exclude-match    https://github.com/organizations/*
// @exclude-match    https://github.com/orgs/*
// @exclude-match    https://github.com/pricing*
// @exclude-match    https://github.com/search*
// @exclude-match    https://github.com/security*
// @exclude-match    https://github.com/sessions/*
// @exclude-match    https://github.com/settings/*
// @exclude-match    https://github.com/site*
// @exclude-match    https://github.com/team*
// @exclude-match    https://github.com/topics*
// @exclude-match    https://github.com/trending*
// @exclude-match    https://github.com/users/*/projects/*
// @version          1.7.2
// @createdAt        4/06/2020
// @author           StaticPH
// @description      Adds a navigation tab for faster access to the 'Network' page of a repository.
// @license          MIT
// @updateURL        https://raw.githubusercontent.com/StaticPH/Userscripts/master/github_repo_network_tab.user.js
// @downloadURL      https://raw.githubusercontent.com/StaticPH/Userscripts/master/github_repo_network_tab.user.js
// @homepageURL      https://github.com/StaticPH/UserScripts
// @supportURL       https://github.com/StaticPH/UserScripts/issues
// @icon             https://github.githubassets.com/pinned-octocat.svg
// @grant            none
// @run-at           document-idle
// @noframes
// ==/UserScript==

(function(){
	'use strict';

	/* Determine what repository we are looking at */
	let here = (function getRepoAddress(){
		return location.pathname.split('/', 3).slice(1).join('/');
	})();

	/* Honestly, I feel like creating the HTML directly is less of a hassle than creating all the elements with JavaScript */
	function createBigNetworkTabHTML(){
		// Exclude analytical "data-ga-click" and "data-selected-links" attributes
		return 	'<a class="js-selected-navigation-item UnderlineNav-item hx_underlinenav-item no-wrap js-responsive-underlinenav-item" data-tab-item="i2_1network-tab" href="/' + here + '/network" id="bigNetworkTab">\n' +
				'	<svg class="octicon octicon-forked UnderlineNav-octicon d-none d-sm-inline" xmlns="http://www.w3.org/2000/svg" height="16" viewBox="0 0 10 16" width="10" aria-hidden="true">\n' +
				'		<path fill-rule="evenodd" d="M8 1a1.993 1.993 0 00-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 002 1a1.993 1.993 0 00-1 3.72V6.5l3 3v1.78A1.993 1.993 0 005 15a1.993 1.993 0 001-3.72V9.5l3-3V4.72A1.993 1.993 0 008 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/>\n' +
				'	</svg>\n' +
				'	<span data-content="Network">\n' +
				'		Network\n' +
				'	</span">\n' +
				'</a>\n';
				//TODO: Intelligently determine if the <a> link element should have 'style="visibility:hidden;"' to start with?
	}

	/* Used when the window size is small enough that the repository header gets combined with the site header */
	function createSmallNetworkTabHTML(){
		// This function may not be useful following one of the github ui refreshes since it was first implemented; Leaving it here for now.
		// Exclude analytical "data-ga-click" and "data-selected-links" attributes
		return	'<a class="js-selected-navigation-item reponav-item" href="/' + here + '/network" id="smallNetworkTab">\n' +
				'	Network\n' +
				'</a>';
	}

	//TODO: Intelligently determine if the list element should be hidden when first added
	function createNetworkTabInDropdownHTML(){
		// Exclude analytical "data-ga-click" and "data-selected-links" attributes
		return	'<li data-menu-item="i2_1network-tab" id="networkTabDropdown">\n' +
				'	<a role="menu-item" class="js-selected-navigation-item dropdown-item" href="/' + here + '/network">\n' +
				'		Network\n' +
				'	</a>\n' +
				'<li>';
	}

	//TODO: Consider insertion at Nth element position, rather than relative to PR tab.
	setTimeout(function wait(){
		/* Find the 'Pull Requests' tab; inserting the new Network tab immediately after it ensures consistent placement. */
		const repoPullsTab = document.querySelectorAll('[data-selected-links*="repo_pulls"]');
		const dropdownRetryLimit = 5;
		let dropdownRetries = 0;

		// Wait until the page loads in enough to have the 'Pull Requests' tab in the repository header, so that it can be used as a point of reference for element insertion
		if (repoPullsTab.length !== 0){
			repoPullsTab[0].insertAdjacentHTML('afterend', createBigNetworkTabHTML());
			document.getElementById('bigNetworkTab') && console.debug('Added big Network tab.');

			if (repoPullsTab.length > 1){
				repoPullsTab[1].insertAdjacentHTML('afterend', createSmallNetworkTabHTML());
				document.getElementById('smallNetworkTab') && console.debug('Added small Network tab.');
			}

//			setTimeout(function foo(){
//				if (document.querySelector('[data-selected-links*="repo_network"]')){
//					console.log("Yup, still there");
//				}
//				// I don't know what causes the element to get deleted sometimes, and I don't know why the developer console doesnt update when
//				// navigating to another (or the current) tab under whatever condition causes the former (but fixes itself if the page is refreshed).
//				// This is immensely bothersome, but I have no idea how to fix it short of just checking every few seconds and adding it if not found.
//			}, 400);
// TODO: MutationObservers don't exactly lend themselves to watching for the creation of a specific element that doesn't already exist at some point in time. Find an alternative.

			setTimeout(function waitmore(){
				const pullsDropdownItem = document.querySelector('details-menu li[data-menu-item="i2pull-requests-tab"]');
				if (pullsDropdownItem){
					pullsDropdownItem.insertAdjacentHTML('afterend', createNetworkTabInDropdownHTML());
					document.getElementById('networkTabDropdown') && console.debug('Added Network tab item to dropdown.');
				}
				else if (dropdownRetries >= dropdownRetryLimit){
					console.log(`Number of attempts at adding Network tab to dropdown have exceeded the limit of ${dropdownRetryLimit} attempts. Giving up.`);
				}
				else{
					console.log(`Waiting ${(dropdownRetries * 500) + 500}ms for page to load further before attempting insertion of dropdown-item.`);
					dropdownRetries++;
					setTimeout(waitmore, (dropdownRetries * 500) + 500);
				}
			});

			if (location.pathname.endsWith(here + '/network') || location.pathname.endsWith(here + '/network/')){
				let networkTab = document.querySelector('[data-tab-item="i2_1network-tab"]');
				let insightsTab = document.querySelector('[data-tab-item="i7insights-tab"]');

				if (insightsTab /*&& insightsTab.hasAttribute('aria-current')*/){
					insightsTab.removeAttribute('aria-current');
					insightsTab.classList.remove('selected');
				}
				if (networkTab){
					networkTab.classList.add('selected');
				}
			}
		}
		else{
			console.log('Waiting 300ms for page to load further.');
			setTimeout(wait, 300);
		}
	});
})();