/**
 * `modules/adsense` data store: adblocker.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import invariant from 'invariant';
import { detectAnyAdblocker } from 'just-detect-adblock';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { STORE_NAME } from './constants';

// Actions
const CHECK_ADBLOCKER = 'CHECK_ADBLOCKER';
const RECEIVE_IS_ADBLOCKER_ACTIVE = 'RECEIVE_IS_ADBLOCKER_ACTIVE';

export const initialState = {
	isAdBlockerActive: undefined,
};

export const actions = {
	*checkAdBlocker() {
		return yield {
			payload: {},
			type: CHECK_ADBLOCKER,
		};
	},
	receiveIsAdBlockerActive( isAdBlockerActive ) {
		invariant( 'boolean' === typeof isAdBlockerActive, 'isAdBlockerActive must be boolean.' );
		return {
			payload: { isAdBlockerActive },
			type: RECEIVE_IS_ADBLOCKER_ACTIVE,
		};
	},
};

export const controls = {
	[ CHECK_ADBLOCKER ]: async () => {
		if ( await detectAnyAdblocker() ) {
			return true;
		}
		// The above is good about detecting most adblockers.
		// For the rest, we'll make a placeholder request to the favicon with some
		// additional stuff in the query string to (hopefully) trigger a filter.
		// If this throws, then the fetch request failed completely and we'll assume it was blocked.
		try {
			await fetch(
				'/favicon.ico?google-site-kit=/adsense/pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
				{
					credentials: 'omit',
					// Don't follow any redirects; we only care about this request being blocked or not.
					redirect: 'manual',
				}
			);
		} catch {
			return true;
		}
		return false;
	},
};

export const reducer = ( state, { payload, type } ) => {
	switch ( type ) {
		case RECEIVE_IS_ADBLOCKER_ACTIVE: {
			const { isAdBlockerActive } = payload;

			return {
				...state,
				isAdBlockerActive,
			};
		}

		default: {
			return state;
		}
	}
};

export const resolvers = {
	*isAdBlockerActive() {
		const registry = yield Data.commonActions.getRegistry();
		const isAdBlockerActive = registry.select( STORE_NAME ).isAdBlockerActive();

		// If ad blocker status was already detected, consider it fulfilled
		// and don't check the global.
		if ( undefined !== isAdBlockerActive ) {
			return;
		}

		const detected = yield actions.checkAdBlocker();

		yield actions.receiveIsAdBlockerActive( detected );
	},
};

export const selectors = {
	/**
	 * Returns whether an ad blocker is active on the client.
	 *
	 * @since 1.9.0
	 *
	 * @param {Object} state Data store's state.
	 * @return {boolean|undefined} True or false depending on whether an ad blocker is active; `undefined` if not loaded.
	 */
	isAdBlockerActive( state ) {
		const { isAdBlockerActive } = state;

		return isAdBlockerActive;
	},
};

export default {
	initialState,
	actions,
	controls,
	reducer,
	resolvers,
	selectors,
};

@@ -784,16 +784,98 @@
 lock';%0A%0A
+/**%0A * WordPress dependencies%0A */%0Aimport %7B addQueryArgs %7D from '@wordpress/url';%0A%0A
 /**%0A * I
@@ -1976,22 +1976,173 @@
 %09%09%09%09
-'/favicon.ico?
+addQueryArgs(%0A%09%09%09%09%09'/favicon.ico',%0A%09%09%09%09%09%7B%0A%09%09%09%09%09%09// The name of the parameter here doesn't really matter%0A%09%09%09%09%09%09// since adblockers look at the URL as a whole.%0A%09%09%09%09%09%09'
 goog
@@ -2152,17 +2152,20 @@
 site-kit
-=
+': '
 /adsense
@@ -2222,16 +2222,103 @@
 le.js',%0A
+%09%09%09%09%09%09// Add a timestamp for cache-busting.%0A%09%09%09%09%09%09timestamp: Date.now(),%0A%09%09%09%09%09%7D%0A%09%09%09%09),%0A
 %09%09%09%09%7B%0A%09%09

Refactor with addQueryArgs and add timestamp.