package com.hubspot.baragon.agent.lbs;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Charsets;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.baragon.agent.config.LoadBalancerConfiguration;
import com.hubspot.baragon.exceptions.InvalidConfigException;
import com.hubspot.baragon.exceptions.LbAdapterExecuteException;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.exec.ExecuteWatchdog;
import org.apache.commons.exec.PumpStreamHandler;

@Singleton
public class LocalLbAdapter {
  private final LoadBalancerConfiguration loadBalancerConfiguration;

  @Inject
  public LocalLbAdapter(LoadBalancerConfiguration loadBalancerConfiguration) {
    this.loadBalancerConfiguration = loadBalancerConfiguration;
  }

  private void executeWithTimeout(CommandLine command, int timeout) throws LbAdapterExecuteException, IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DefaultExecutor executor = new DefaultExecutor();

    executor.setStreamHandler(new PumpStreamHandler(baos));
    executor.setWatchdog(new ExecuteWatchdog(timeout));

    try {
      executor.execute(command);
    } catch (ExecuteException e) {
      throw new LbAdapterExecuteException(baos.toString(Charsets.UTF_8.name()), e, command.toString());
    }
  }

  @Timed
  public void checkConfigs() throws InvalidConfigException {
    try {
      executeWithTimeout(CommandLine.parse(loadBalancerConfiguration.getCheckConfigCommand()), loadBalancerConfiguration.getCommandTimeoutMs());
    } catch (LbAdapterExecuteException e) {
      throw new InvalidConfigException(e.getOutput());
    } catch (IOException e) {
      throw new InvalidConfigException(e.getMessage());
    }
  }

  @Timed
  public void reloadConfigs() throws LbAdapterExecuteException, IOException {
    executeWithTimeout(CommandLine.parse(loadBalancerConfiguration.getReloadConfigCommand()), loadBalancerConfiguration.getCommandTimeoutMs());
  }
}

@@ -100,16 +100,313 @@
 ption;%0A%0A
+import org.apache.commons.exec.CommandLine;%0Aimport org.apache.commons.exec.DefaultExecutor;%0Aimport org.apache.commons.exec.ExecuteException;%0Aimport org.apache.commons.exec.ExecuteWatchdog;%0Aimport org.apache.commons.exec.PumpStreamHandler;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 import c
@@ -750,272 +750,110 @@
 on;%0A
-import org.apache.commons.exec.CommandLine;%0Aimport org.apache.commons.exec.DefaultExecutor;%0Aimport org.apache.commons.exec.ExecuteException;%0Aimport org.apache.commons.exec.ExecuteWatchdog;%0Aimport org.apache.commons.exec.PumpStreamHandler;%0A%0A@Singleton%0Apublic class 
+%0A@Singleton%0Apublic class LocalLbAdapter %7B%0A  private static final Logger LOG = LoggerFactory.getLogger(
 Loca
@@ -854,34 +854,41 @@
 r(LocalLbAdapter
- %7B
+.class);%0A
 %0A  private final
@@ -1110,20 +1110,19 @@
 private 
-void
+int
  execute
@@ -1461,24 +1461,31 @@
 try %7B%0A      
+return 
 executor.exe
@@ -1734,16 +1734,90 @@
  %7B%0A     
+ final long start = System.currentTimeMillis();%0A      final int exitCode =
  execute
@@ -1944,24 +1944,191 @@
 meoutMs());%0A
+      LOG.debug(%22Checked configs via '%7B%7D' in %7B%7Dms (exit code = %7B%7D)%22, loadBalancerConfiguration.getCheckConfigCommand(), System.currentTimeMillis() - start, exitCode);%0A
     %7D catch 
@@ -2397,24 +2397,96 @@
 eption %7B%0A   
+ final long start = System.currentTimeMillis();%0A    final int exitCode =
  executeWith
@@ -2614,14 +2614,181 @@
 tMs());%0A
+    LOG.debug(%22Reloaded configs via '%7B%7D' in %7B%7Dms (exit code = %7B%7D)%22, loadBalancerConfiguration.getReloadConfigCommand(), System.currentTimeMillis() - start, exitCode);%0A
   %7D%0A%7D%0A

add logging to check and reload commands