package com.hubspot.baragon.service.resources;

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import com.amazonaws.AmazonClientException;
import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
import com.amazonaws.services.elasticloadbalancing.model.DeregisterInstancesFromLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.DeregisterInstancesFromLoadBalancerResult;
import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersRequest;
import com.amazonaws.services.elasticloadbalancing.model.DescribeLoadBalancersResult;
import com.amazonaws.services.elasticloadbalancing.model.Instance;
import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription;
import com.amazonaws.services.elasticloadbalancing.model.RegisterInstancesWithLoadBalancerRequest;
import com.amazonaws.services.elasticloadbalancing.model.RegisterInstancesWithLoadBalancerResult;
import com.google.common.base.Optional;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.hubspot.baragon.auth.NoAuth;
import com.hubspot.baragon.service.BaragonServiceModule;
import com.hubspot.baragon.service.config.ElbConfiguration;
import com.hubspot.baragon.service.exceptions.BaragonNotFoundException;
import com.hubspot.baragon.service.exceptions.BaragonWebException;

@Path("/elbs")
@Produces(MediaType.APPLICATION_JSON)
public class ElbResource {
  private final AmazonElasticLoadBalancingClient elbClient;
  private final Optional<ElbConfiguration> config;

  @Inject
  public ElbResource(@Named(BaragonServiceModule.BARAGON_AWS_ELB_CLIENT_V1) AmazonElasticLoadBalancingClient elbClient,
                     Optional<ElbConfiguration> config) {
    this.elbClient = elbClient;
    this.config = config;
  }


  @GET
  @NoAuth
  public List<LoadBalancerDescription> getAllElbs() {
    if (config.isPresent()) {
      return elbClient.describeLoadBalancers().getLoadBalancerDescriptions();
    } else {
      throw new BaragonWebException("ElbSync and related actions are not currently enabled");
    }
  }

  @GET
  @NoAuth
  @Path("/{elbName}")
  public LoadBalancerDescription getElb(@PathParam("elbName") String elbName) {
    if (config.isPresent()) {
      try {
        DescribeLoadBalancersRequest request = new DescribeLoadBalancersRequest(Arrays.asList(elbName));
        DescribeLoadBalancersResult result = elbClient.describeLoadBalancers(request);
        for (LoadBalancerDescription elb : result.getLoadBalancerDescriptions()) {
          if (elb.getLoadBalancerName().equals(elbName)) {
            return elb;
          }
        }
      } catch (AmazonClientException e) {
        throw new BaragonWebException(String.format("AWS Client Error: %s", e));
      }
      throw new BaragonNotFoundException(String.format("ELB with name %s not found", elbName));
    } else {
      throw new BaragonWebException("EElbSync and related actions are not currently enabled");
    }
  }

  @POST
  @Path("/{elbName}/update")
  public RegisterInstancesWithLoadBalancerResult addToElb(@PathParam("elbName") String elbName, @QueryParam("instanceId") String instanceId) {
    if (config.isPresent()) {
      RegisterInstancesWithLoadBalancerRequest request = new RegisterInstancesWithLoadBalancerRequest(elbName, Arrays.asList(new Instance(instanceId)));
      return elbClient.registerInstancesWithLoadBalancer(request);
    } else {
      throw new BaragonWebException("ElbSync and related actions are not currently enabled");
    }
  }

  @DELETE
  @Path("/{elbName}/update")
  public DeregisterInstancesFromLoadBalancerResult removeFromElb(@PathParam("elbName") String elbName, @QueryParam("instanceId") String instanceId) {
    if (config.isPresent()) {
      DeregisterInstancesFromLoadBalancerRequest request = new DeregisterInstancesFromLoadBalancerRequest(elbName, Arrays.asList(new Instance(instanceId)));
      return elbClient.deregisterInstancesFromLoadBalancer(request);
    } else {
      throw new BaragonWebException("ElbSync and related actions are not currently enabled");
    }
  }
}

@@ -639,32 +639,207 @@
 BalancerResult;%0A
+import com.amazonaws.services.elasticloadbalancing.model.DescribeInstanceHealthRequest;%0Aimport com.amazonaws.services.elasticloadbalancing.model.DescribeInstanceHealthResult;%0A
 import com.amazo
@@ -1062,16 +1062,88 @@
 stance;%0A
+import com.amazonaws.services.elasticloadbalancing.model.InstanceState;%0A
 import c
@@ -3380,16 +3380,669 @@
 ption(%22E
+lbSync and related actions are not currently enabled%22);%0A    %7D%0A  %7D%0A%0A  @GET%0A  @NoAuth%0A  @Path(%22/%7BelbName%7D/instances%22)%0A  public List%3CInstanceState%3E getInstancesByElb(@PathParam(%22elbName%22) String elbName) %7B%0A    if (config.isPresent()) %7B%0A      try %7B%0A        DescribeInstanceHealthRequest request = new DescribeInstanceHealthRequest(elbName);%0A        DescribeInstanceHealthResult result = elbClient.describeInstanceHealth(request);%0A        return result.getInstanceStates();%0A      %7D catch (AmazonClientException exn) %7B%0A        throw new BaragonWebException(String.format(%22AWS Client Error %25s%22, exn));%0A      %7D%0A    %7D else %7B%0A      throw new BaragonWebException(%22
 ElbSync 

Add additional endpoint to get for ELB instances