import { createTokenAuth } from '@octokit/auth-token';

export const getGitHubToken = async () => {
	const gitHubToken = localStorage.getItem('gitHubToken');
	const auth = createTokenAuth(gitHubToken);
	const { token } = await auth();
	return token;
};

export const fetchWithTimeout: typeof fetch = (input: string | Request, init?: RequestInit) => {
	const timeout = 30 * 1000; // 30 seconds
	return new Promise<Response>((resolve, reject) => {
		const timeoutHandle = setTimeout(() => trackAndReject('timeout'), timeout);
		function trackAndResolve(response: Response) {
			clearTimeout(timeoutHandle);
			resolve(response);
		}
		function trackAndReject(reason: any) {
			clearTimeout(timeoutHandle);
			reject(reason);
		}
		fetch(input, init).then(trackAndResolve, trackAndReject);
	});
};

export async function createGitHubRequest(
	url: string,
	init?: RequestInit,
	requiresAuthorization: boolean = true,
	contentType: string = 'application/json'
): Promise<Request> {
	init = init || {};
	init.mode = 'cors';

	if (requiresAuthorization && !init.credentials) {
		init.credentials = 'omit';
	}

	const request = new Request(url, init);
	if (requiresAuthorization) {
		const token = await getGitHubToken();
		if (token) {
			request.headers.set('Authorization', `token ${token}`);
		}
	}

	if (request.method === 'PUT' || request.method === 'POST') {
		// if we have a multipart upload, let the browser determine the boundary.
		if (contentType !== 'multipart/form-data') {
			request.headers.set('Content-Type', contentType);
		}
	}
	return request;
}
