package com.hubspot.singularity.data.history;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.ResultSetMapper;

import com.google.common.base.Optional;
import com.hubspot.singularity.DeployState;
import com.hubspot.singularity.ExtendedTaskState;
import com.hubspot.singularity.SingularityDeploy;
import com.hubspot.singularity.SingularityDeployHistory;
import com.hubspot.singularity.SingularityDeployMarker;
import com.hubspot.singularity.SingularityDeployResult;
import com.hubspot.singularity.SingularityDeployStatistics;
import com.hubspot.singularity.SingularityLoadBalancerUpdate;
import com.hubspot.singularity.SingularityRequest;
import com.hubspot.singularity.SingularityRequestHistory;
import com.hubspot.singularity.SingularityRequestHistory.RequestHistoryType;
import com.hubspot.singularity.SingularityServiceModule;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.SingularityTaskIdHistory;

public class SingularityMappers {

  public static class SingularityBytesMapper implements ResultSetMapper<byte[]> {

    @Override
    public byte[] map(int index, ResultSet r, StatementContext ctx) throws SQLException {
      return r.getBytes("bytes");
    }

  }

  public static class SingularityRequestIdMapper implements ResultSetMapper<String> {

    @Override
    public String map(int index, ResultSet r, StatementContext ctx) throws SQLException {
      return r.getString("requestId");
    }

  }

  public static class SingularityRequestHistoryMapper implements ResultSetMapper<SingularityRequestHistory> {

    @Override
    public SingularityRequestHistory map(int index, ResultSet r, StatementContext ctx) throws SQLException {
      return new SingularityRequestHistory(r.getTimestamp("createdAt").getTime(), Optional.fromNullable(r.getString("user")), RequestHistoryType.valueOf(r.getString("requestState")), SingularityRequest.fromBytes(r.getBytes("request"),
          SingularityServiceModule.OBJECT_MAPPER));
    }

  }

  public static class SingularityTaskIdHistoryMapper implements ResultSetMapper<SingularityTaskIdHistory> {

    @Override
    public SingularityTaskIdHistory map(int index, ResultSet r, StatementContext ctx) throws SQLException {
      String lastTaskStatus = r.getString("lastTaskStatus");

      Optional<ExtendedTaskState> lastTaskState = Optional.absent();

      if (lastTaskStatus != null) {
        lastTaskState = Optional.of(ExtendedTaskState.valueOf(lastTaskStatus));
      }

      return new SingularityTaskIdHistory(SingularityTaskId.fromString(r.getString("taskId")), r.getTimestamp("updatedAt").getTime(), lastTaskState);
    }

  }

  public static class SingularityDeployHistoryLiteMapper implements ResultSetMapper<SingularityDeployHistory> {

    @Override
    public SingularityDeployHistory map(int index, ResultSet r, StatementContext ctx) throws SQLException {
      SingularityDeployMarker marker = new SingularityDeployMarker(r.getString("requestId"), r.getString("deployId"), r.getTimestamp("createdAt").getTime(), Optional.fromNullable(r.getString("user")));
      SingularityDeployResult deployState = new SingularityDeployResult(DeployState.valueOf(r.getString("deployState")), Optional.<String> absent(), Optional.<SingularityLoadBalancerUpdate> absent(), r.getTimestamp("deployStateAt").getTime());

      return new SingularityDeployHistory(Optional.of(deployState), marker, Optional.<SingularityDeploy> absent(), Optional.<SingularityDeployStatistics> absent());
    }

  }

}

@@ -188,16 +188,73 @@
 tMapper;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -1108,16 +1108,104 @@
 pers %7B%0A%0A
+  private static final Logger LOG = LoggerFactory.getLogger(SingularityMappers.class);%0A%0A
   public
@@ -2441,16 +2441,114 @@
 %7B%0A      
+final SingularityTaskId taskId = SingularityTaskId.fromString(r.getString(%22taskId%22));%0A      final 
 String l
@@ -2701,16 +2701,32 @@
 null) %7B%0A
+        try %7B%0A  
         
@@ -2799,24 +2799,175 @@
 us));%0A      
+  %7D catch (IllegalArgumentException e) %7B%0A          LOG.warn(%22Found invalid taskState %7B%7D in DB for task %7B%7D%22, lastTaskState, taskId, e);%0A        %7D%0A      
 %7D%0A%0A      ret
@@ -3003,59 +3003,14 @@
 ory(
-SingularityTaskId.fromString(r.getString(%22
 taskId
-%22))
 , r.

handle invalid task states