package mil.dds.anet.graphql;

import graphql.language.IntValue;
import graphql.schema.Coercing;
import graphql.schema.GraphQLScalarType;
import java.math.BigInteger;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public final class GraphQlDateTimeType {

  private GraphQlDateTimeType() {}

  private static final Coercing<Instant, Long> coercing = new Coercing<Instant, Long>() {
    @Override
    public Long serialize(Object input) {
      return ((Instant) input).toEpochMilli();
    }

    @Override
    public Instant parseValue(Object input) throws NumberFormatException {
      if (input instanceof Long) {
        return Instant.ofEpochMilli((Long) input);
      } else if (input instanceof String) {
        return ZonedDateTime.parse((String) input, DateTimeFormatter.ISO_DATE_TIME).toInstant();
      } else {
        return Instant.ofEpochMilli(Long.parseLong(input.toString()));
      }
    }

    @Override
    public Instant parseLiteral(Object input) {
      if (input.getClass().equals(IntValue.class)) {
        BigInteger value = ((IntValue) input).getValue();
        return Instant.ofEpochMilli(value.longValue());
      }
      throw new RuntimeException("Unexpected input, expected Unix Millis as long");
    }
  };

  public static GraphQLScalarType getInstance() {
    return GraphQLScalarType.newScalar().name("Instant").coercing(coercing).build();
  }
}

@@ -90,16 +90,170 @@
 ercing;%0A
+import graphql.schema.CoercingParseLiteralException;%0Aimport graphql.schema.CoercingParseValueException;%0Aimport graphql.schema.CoercingSerializeException;%0A
 import g
@@ -314,16 +314,52 @@
 nteger;%0A
+import java.time.DateTimeException;%0A
 import j
@@ -663,33 +663,93 @@
 lize(Object 
-input) %7B%0A
+dataFetcherResult) throws CoercingSerializeException %7B%0A      try %7B%0A  
       return
@@ -760,20 +760,32 @@
 nstant) 
-inpu
+dataFetcherResul
 t).toEpo
@@ -791,24 +791,121 @@
 ochMilli();%0A
+      %7D catch (ArithmeticException e) %7B%0A        throw new CoercingSerializeException(e);%0A      %7D%0A
     %7D%0A%0A    @
@@ -968,20 +968,26 @@
 ows 
-NumberFormat
+CoercingParseValue
 Exce
@@ -990,24 +990,38 @@
 Exception %7B%0A
+      try %7B%0A  
       if (in
@@ -1039,24 +1039,26 @@
 eof Long) %7B%0A
+  
         retu
@@ -1098,24 +1098,26 @@
 put);%0A      
+  
 %7D else if (i
@@ -1146,24 +1146,26 @@
 ) %7B%0A        
+ 
+ 
 return Zoned
@@ -1243,24 +1243,26 @@
 nt();%0A      
+  
 %7D else %7B%0A   
@@ -1258,16 +1258,18 @@
  else %7B%0A
+  
         
@@ -1327,24 +1327,146 @@
 String()));%0A
+        %7D%0A      %7D catch (DateTimeException %7C NumberFormatException e) %7B%0A        throw new CoercingParseValueException(e);%0A
       %7D%0A    
@@ -1527,16 +1527,53 @@
 t input)
+ throws CoercingParseLiteralException
  %7B%0A     
@@ -1628,16 +1628,22 @@
         
+final 
 BigInteg
@@ -1768,15 +1768,28 @@
 new 
-Runtime
+CoercingParseLiteral
 Exce

Make custom scalar conform to Coercing contract