package com.networknt.oauth.github;

import com.networknt.client.Http2Client;
import com.networknt.config.Config;
import com.networknt.exception.ClientException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.undertow.client.ClientConnection;
import io.undertow.client.ClientRequest;
import io.undertow.client.ClientResponse;
import io.undertow.util.Headers;
import io.undertow.util.Methods;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xnio.IoUtils;
import org.xnio.OptionMap;

import java.net.URI;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

/**
 * This is the utility to access github.com api. Before calling this, you need to download the certificate from
 * api.github.com and import it into the client.truststore
 *
 */
public class GithubUtil {
	private final static Logger logger = LoggerFactory.getLogger(GithubUtil.class);
	private final static String CONFIG_GITHUB = "github";
	private final static String CONFIG_SECRET = "secret";
	private final static String GITHUB_TOKEN = "githubToken";

	private final static GithubConfig config = (GithubConfig) Config.getInstance().getJsonObjectConfig(CONFIG_GITHUB,
			GithubConfig.class);
	private final static Map<String, Object> secret = Config.getInstance().getJsonMapConfig(CONFIG_SECRET);
	private final static String githubToken = (String) secret.get(GITHUB_TOKEN);

	/**
	 * Get the user roles from github.com repository.
	 *
	 * @param username String username
	 * @return A set of group attributes for the username on github DB. You can
	 *         only call this method if the username has been authenticated
	 * @throws ClientException ClientException
	 */
	public static Set<String> authorize(String username) throws Exception {
		Set<String> groups = new HashSet<String>();

		String apiURL = config.protocol + "://" + config.host + config.pathPrefix;
		String contentsURL = "/repos/" + config.owner + "/" + config.repo + "/contents/" + config.path;

		final Http2Client client = Http2Client.getInstance();
        final CountDownLatch latch = new CountDownLatch(1);
        
        final ClientConnection connection = client.connect(new URI(apiURL), Http2Client.WORKER, Http2Client.SSL, Http2Client.POOL, OptionMap.EMPTY).get();
        final AtomicReference<ClientResponse> reference = new AtomicReference<>();
        try {
        	final ClientRequest request = new ClientRequest().setMethod(Methods.GET).setPath(contentsURL);
			request.getRequestHeaders().put(Headers.AUTHORIZATION, "token " + githubToken);
			request.getRequestHeaders().put(Headers.HOST, "api.github.com");
			request.getRequestHeaders().put(Headers.ACCEPT, "application/vnd.github.v3.raw");
			request.getRequestHeaders().put(Headers.CACHE_CONTROL, "no-cache");
			request.getRequestHeaders().put(Headers.USER_AGENT, "stevehu");
			connection.sendRequest(request, client.createClientCallback(reference, latch));
			latch.await(); 
        } catch (Exception e) {
            logger.error("Exception: ", e);
            throw new ClientException(e);
        } finally {
            IoUtils.safeClose(connection);
        }
		int statusCode = reference.get().getResponseCode();
		System.out.println("statusCode = " + statusCode);
		String body = reference.get().getAttachment(Http2Client.RESPONSE_BODY);
		System.out.println("testHttp2Get: statusCode = " + statusCode + " body = " + body);

		ObjectMapper objectMapper = new ObjectMapper();
		List<GithubMetadata> listMeta = objectMapper.readValue(body, new TypeReference<List<GithubMetadata>>(){});
		for (GithubMetadata meta : listMeta) {
			if (meta.github_username.equals(username)) {
				logger.info(meta.github_username + " is attached to the following primary group: " + meta.groups.primary + " and secondary groups: " + Arrays.toString(meta.groups.secondary));
			}
		}
		
		return groups;
	}

}

@@ -2056,28 +2056,8 @@
 host
- + config.pathPrefix
 ;%0A%09%09
@@ -2076,16 +2076,36 @@
 ntsURL =
+ config.pathPrefix +
  %22/repos
@@ -2172,16 +2172,18 @@
 g.path;%0A
+%09%09
 %0A%09%09final
@@ -2792,24 +2792,19 @@
 ST, 
-%22api.github.com%22
+config.host
 );%0A%09
@@ -3585,16 +3585,44 @@
 body);%0A%0A
+%09%09if (statusCode == 200) %7B%0A%09
 %09%09Object
@@ -3663,16 +3663,17 @@
 pper();%0A
+%09
 %09%09List%3CG
@@ -3775,16 +3775,17 @@
 )%7B%7D);%0A%09%09
+%09
 for (Git
@@ -3815,16 +3815,17 @@
 Meta) %7B%0A
+%09
 %09%09%09if (m
@@ -3860,24 +3860,25 @@
 sername)) %7B%0A
+%09
 %09%09%09%09logger.i
@@ -4045,16 +4045,22 @@
 dary));%0A
+%09%09%09%09%7D%0A
 %09%09%09%7D%0A%09%09%7D

update github request url