package ca.ryangreen.examples;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.EnvironmentVariableCredentialsProvider;
import com.amazonaws.http.HttpMethodName;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import ca.ryangreen.apigateway.generic.GenericApiGatewayClient;
import ca.ryangreen.apigateway.generic.GenericApiGatewayClientBuilder;
import ca.ryangreen.apigateway.generic.GenericApiGatewayException;
import ca.ryangreen.apigateway.generic.GenericApiGatewayRequestBuilder;
import ca.ryangreen.apigateway.generic.GenericApiGatewayResponse;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import java.util.Iterator;
import java.util.Map;

public class Main implements RequestStreamHandler {

    // this function is exposed by /hello and is authenticated with IAM
    public void hello(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        ProxyResponse resp = new ProxyResponse("200", "{\"message\" : \"Hello World\"}");
        String apiIntputStream = new Scanner(inputStream).useDelimiter("\\A").next();
        System.out.println("Response: " + apiIntputStream);

        String responseString = new ObjectMapper(new JsonFactory()).writeValueAsString(resp);

        OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
        writer.write(responseString);
        writer.close();
    }

    // this function is exposed by /sdk-example and is unauthenticated
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {

        String apiIntputStream = new Scanner(inputStream).useDelimiter("\\A").next();
        JsonFactory factory = new JsonFactory();
        ObjectMapper mapper = new ObjectMapper(factory);
        JsonNode rootNode = mapper.readTree(apiIntputStream);
        String myApiId = rootNode.path("requestContext").path("apiId").asText();

        // just for fun, output all details to logs
        System.out.println("Response: " + apiIntputStream);
        Iterator<Map.Entry<String,JsonNode>> nodes = rootNode.get("requestContext").fields();
        while (nodes.hasNext()) {
              Map.Entry<String,JsonNode> field = nodes.next();
              System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
        }

        final GenericApiGatewayClient client = new GenericApiGatewayClientBuilder()
                .withClientConfiguration(new ClientConfiguration())
                .withCredentials(new EnvironmentVariableCredentialsProvider())
                .withEndpoint("https://" + myApiId + ".execute-api.us-west-2.amazonaws.com") // your API ID
                .withRegion(Region.getRegion(Regions.fromName("us-west-2")))
                .build();

        GenericApiGatewayResponse apiResponse;
        ProxyResponse resp;
        try {
            apiResponse = client.execute(  // throws exception for non-2xx response
                    new GenericApiGatewayRequestBuilder()
                            .withHttpMethod(HttpMethodName.GET)
                            .withResourcePath("/Prod/hello").build());

            System.out.println("Response: " + apiResponse.getBody());
            System.out.println("Status: " + apiResponse.getHttpResponse().getStatusCode());

            resp = new ProxyResponse("200", apiResponse.getBody());

        } catch (GenericApiGatewayException e) {
            System.out.println("Client threw exception " + e);
            resp = new ProxyResponse("400", e.getMessage());
        }

        String responseString = new ObjectMapper(new JsonFactory()).writeValueAsString(resp);
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
        writer.write(responseString);
        writer.close();
    }

    private class ProxyResponse {
        private String statusCode;
        private String body;

        public ProxyResponse(String statusCode, String body) {
            this.statusCode = statusCode;
            this.body = body;
        }

        public String getStatusCode() {
            return statusCode;
        }

        public String getBody() {
            return body;
        }
    }
}

@@ -1385,154 +1385,8 @@
 %7D%22);
-%0A        String apiIntputStream = new Scanner(inputStream).useDelimiter(%22%5C%5CA%22).next();%0A        System.out.println(%22Response: %22 + apiIntputStream);
 %0A%0A  
@@ -1821,17 +1821,16 @@
 ption %7B%0A
-%0A
         
@@ -1923,75 +1923,25 @@
 Json
-Factory factory = new JsonFactory();%0A        ObjectMapper mapper
+Node rootNode
  = 
+(
 new 
@@ -1957,52 +1957,27 @@
 per(
-factory);%0A        JsonNode rootNode = mapper
+new JsonFactory()))
 .rea
@@ -2081,25 +2081,24 @@
 Text();%0A
-%0A
         
 // just 
@@ -2093,404 +2093,83 @@
     
-// just for fun, output all details to logs%0A        System.out.println(%22Response: %22 + apiIntputStream);%0A        Iterator%3CMap.Entry%3CString,JsonNode%3E%3E nodes = rootNode.get(%22requestContext%22).fields();%0A        while (nodes.hasNext()) %7B%0A              Map.Entry%3CString,JsonNode%3E field = nodes.next();%0A              System.out.println(%22Key: %22 + field.getKey() + %22%5CtValue:%22 + field.getValue());%0A        %7D
+if (myApiId.isEmpty()) %7B myApiId = %22TODO%22; %7D // Not called from API Gateway
 %0A%0A  

Update example to use apiId from requestContext