export async function GetBlueskyDID(PDS, Handle) {
	let request = fetch(PDS + "/xrpc/com.atproto.identity.resolveDid?handle=" + Handle, { method: "GET"})
	.then((response) => response.json());
	return request;
}


// Component 1/4
export async function GetPDSWellKnown() {
	let Data = await fetch("https://bsky.social/.well-known/oauth-authorization-server", {method: "GET"})
	.then((response) => response.json());
	return Data;
}

// Component 2/4
// Many thanks to https://github.com/tonyxu-io/pkce-generator. It was the base for this code.
export async function CreatePKCECodeVerifier() {
	// Generate some Numbers
	let Numbers = new Uint8Array(32);
	crypto.getRandomValues(Numbers);
	// Generate a random string of characters.
	let CodeVerifier = "";
	for (let i in Numbers) {
		CodeVerifier += String.fromCharCode(Numbers[i]);
	}
	// Put this random string into Base64URL format.
	CodeVerifier = btoa(CodeVerifier).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
	return CodeVerifier;
}

export async function CreatePKCECodeChallenge(CodeVerifier) {
	// Generate a code challenge with the code verifier.
	// This is done by first SHA256 encrypting the CodeVerifier, then putting the outputted string into Base64URL format.
	let CodeChallenge = btoa(await sha256(CodeVerifier)).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
	return CodeChallenge;
}

// Component 3/4
export async function CreatePAR() {
	let WellKnown = await GetPDSWellKnown();
	// Some verification mechanism with PAR
	let PAREndpoint = WellKnown.pushed_authorization_request_endpoint;
	
	
	// Token goes into the authorization endpoint
	let AuthEndpoint = WellKnown.authorization_endpoint;
}

// Component 4/4
export async function ClientDPoP() {
	let KeyPair = await crypto.subtle.generateKey({name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]);
	
	// Header
	var Header = {alg: "HS256", typ: "dpop+jwt", jwk: await crypto.subtle.exportKey("jwk", KeyPair.publicKey).then(function(response) {return response})};
	// Payload
	var Payload = {};
	// Payload.jti
	// Payload.htm
	// Payload.htu
	Payload.iat = Math.floor(new Date(Date.now()).getTime() / 1000);
	// Payload.nonce

	var sHeader = JSON.stringify(Header);
	var sPayload = JSON.stringify(Payload);
	var JWT = KJUR.jws.JWS.sign("HS256", sHeader, sPayload, "616161");
	console.log(JWT);
}

export async function ServerDPoP() {
	
}

export async function AssertionJWT(BlueskyClientID) {
	let KeyPair = await crypto.subtle.generateKey({name: "ECDSA", namedCurve: "P-256"}, true, ["sign", "verify"]);
	
	// Header
	var Header = {alg: "HS256", kid: await crypto.subtle.exportKey("jwk", KeyPair.publicKey).then(function(response) {return response})};
	// Payload
	var Payload = {};
	
	Payload.iss = BlueskyClientID;
	Payload.sub = BlueskyClientID;
	// Payload.aud
	// Payload.jti
	Payload.iat = Math.floor(new Date(Date.now()).getTime() / 1000);

	var sHeader = JSON.stringify(Header);
	var sPayload = JSON.stringify(Payload);
	var JWT = KJUR.jws.JWS.sign("HS256", sHeader, sPayload, "838383");
	console.log(JWT);
}

// Stolen from elsewhere.
// Firefox snippet; Slightly edited.
async function sha256(message) {
	// encode as UTF-8
	const MessageBuffer = new TextEncoder().encode(message);                    
	
	// hash the message
	const HashBuffer = await crypto.subtle.digest('SHA-256', MessageBuffer);
	
	// convert ArrayBuffer to Array
	const HashArray = Array.from(new Uint8Array(HashBuffer));
	
	// convert this hashArray to a string
	let string = "";
	for (let i in HashArray) {
		string += String.fromCharCode(HashArray[i]);
	}
	
	return string;
}
