package io.vertx.ext.mongo.impl.codec.json;

import io.vertx.core.json.JsonObject;
import org.bson.BsonDateTime;
import org.bson.BsonDocument;
import org.bson.BsonDocumentReader;
import org.bson.BsonDocumentWriter;
import org.bson.BsonType;
import org.bson.BsonValue;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import org.junit.Test;

import java.time.Instant;
import java.time.OffsetDateTime;

import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME;
import static org.junit.Assert.assertEquals;

/**
 *
 */
public class JsonObjectCodecTest {

  @Test
  public void getBsonType_returnsDateTimeType_WhenValueIsJsonObjectAndContainsDateField() {
    JsonObjectCodec codec = new JsonObjectCodec();

    JsonObject value = new JsonObject();
    value.put(JsonObjectCodec.DATE_FIELD, "2015-05-30T22:50:02+02:00");

    assertEquals(BsonType.DATE_TIME, codec.getBsonType(value));
  }

  @Test
  public void writeDocument_supportBsonDateTime() {
    JsonObjectCodec codec = new JsonObjectCodec();

    OffsetDateTime now = OffsetDateTime.now();
    JsonObject dateValue = new JsonObject();
    dateValue.put(JsonObjectCodec.DATE_FIELD, now.format(ISO_OFFSET_DATE_TIME));
    JsonObject value = new JsonObject();
    value.put("test", dateValue);

    BsonDocument bsonResult = new BsonDocument();
    BsonDocumentWriter writer = new BsonDocumentWriter(bsonResult);

    codec.writeDocument(writer, "", value, EncoderContext.builder().build());

    BsonValue resultValue = bsonResult.get("test");
    assertEquals(BsonType.DATE_TIME, resultValue.getBsonType());
    assertEquals(now.toInstant().toEpochMilli(), resultValue.asDateTime().getValue());
  }

  @Test
  public void readDocument_supportBsonDateTime() {
    JsonObjectCodec codec = new JsonObjectCodec();

    Instant now = Instant.now();
    BsonDocument bson = new BsonDocument();
    bson.append("test", new BsonDateTime(now.toEpochMilli()));

    BsonDocumentReader reader = new BsonDocumentReader(bson);

    JsonObject result = codec.readDocument(reader, DecoderContext.builder().build());

    JsonObject resultValue = result.getJsonObject("test");
    assertEquals(now, OffsetDateTime.parse(resultValue.getString(JsonObjectCodec.DATE_FIELD)).toInstant());
  }
}

@@ -421,16 +421,45 @@
 ateTime;
+%0Aimport java.time.ZoneOffset;
 %0A%0Aimport
@@ -2291,11 +2291,970 @@
 ());%0A  %7D
+%0A%0A  @Test%0A  public void writeDocument_supportBsonDateTimeWithMillis() %7B%0A    JsonObjectCodec codec = new JsonObjectCodec();%0A%0A    JsonObject dateValue = new JsonObject();%0A    dateValue.put(JsonObjectCodec.DATE_FIELD, %222011-12-03T10:15:30.500+01:00%22);%0A    JsonObject value = new JsonObject();%0A    value.put(%22test%22, dateValue);%0A%0A    BsonDocument bsonResult = new BsonDocument();%0A    BsonDocumentWriter writer = new BsonDocumentWriter(bsonResult);%0A%0A    codec.writeDocument(writer, %22%22, value, EncoderContext.builder().build());%0A%0A    long millis = 1322903730500l;%0A%0A    BsonValue resultValue = bsonResult.get(%22test%22);%0A    assertEquals(BsonType.DATE_TIME, resultValue.getBsonType());%0A    assertEquals(millis, resultValue.asDateTime().getValue());%0A%0A    String back =%0A        OffsetDateTime.ofInstant(Instant.ofEpochMilli(1322903730500l), ZoneOffset.UTC).format(ISO_OFFSET_DATE_TIME);%0A%0A    // we encode always in UTC%0A    assertEquals(%222011-12-03T09:15:30.5Z%22, back);%0A  %7D
 %0A%7D%0A

add a test to proof that milliseconds are properly handled #20 is not correct.