/*
 * Copyright 2015-2017 Canoo Engineering AG.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.canoo.dolphin.impl.converters;

import com.canoo.dolphin.converter.Converter;
import com.canoo.dolphin.converter.ValueConverterException;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class CalenderConverterFactoryTest {

    @Test
    public void testTypeIdentifier() {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Assert.assertEquals(factory.getTypeIdentifier(), CalendarConverterFactory.FIELD_TYPE_CALENDAR);
    }

    @Test
    public void testTypeSupport() {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Assert.assertTrue(factory.supportsType(Calendar.class));
        Assert.assertTrue(factory.supportsType(GregorianCalendar.class));
    }

    @Test
    public void testConverterCreation() {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);
        Assert.assertNotNull(converter);

        converter = factory.getConverterForType(GregorianCalendar.class);
        Assert.assertNotNull(converter);
    }

    @Test
    public void testConversionCurrentDate() throws ValueConverterException {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);

        Calendar calendar = GregorianCalendar.getInstance();
        Object converted = converter.convertToDolphin(calendar);
        Assert.assertNotNull(converted);
        Assert.assertEquals(((Calendar)converter.convertFromDolphin(converted)).getTime(), calendar.getTime());
    }

    @Test
    public void testConversionFixDate() throws ValueConverterException {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);

        Calendar calendar = new GregorianCalendar(2017, 2, 3,4, 5, 6);
        Object converted = converter.convertToDolphin(calendar);
        Assert.assertNotNull(converted);
        Assert.assertEquals(((Calendar)converter.convertFromDolphin(converted)).getTime(), calendar.getTime());
    }

    @Test
    public void testToDolphinConversionFixDate() throws ValueConverterException {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);

        Calendar calendar = new GregorianCalendar(2017, 2, 3,4, 5, 6);
        Object converted = converter.convertToDolphin(calendar);
        Assert.assertNotNull(converted);
        Assert.assertTrue(converted instanceof String);
        Assert.assertEquals(converted, "2017-03-03T03:05:06.000Z");
    }

    @Test
    public void testToDolphinConversionFixDateInUTC() throws ValueConverterException {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);

        Calendar calendar = new GregorianCalendar(2017, 2, 3,4, 5, 6);
        calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
        Object converted = converter.convertToDolphin(calendar);
        Assert.assertNotNull(converted);
        Assert.assertTrue(converted instanceof String);
        Assert.assertEquals(converted, "2017-03-03T04:05:06.000Z");
    }

    @Test
    public void testFromDolphinConversionFixDate() throws ValueConverterException {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);

        String input = "2017-03-03T03:05:06.000Z";

        Object converted = converter.convertFromDolphin(input);
        Assert.assertNotNull(converted);
        Assert.assertTrue(converted instanceof Calendar);

        Calendar calendar = (Calendar) converted;

        Assert.assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("UTC"));
        Assert.assertEquals(calendar.get(Calendar.YEAR), 2017);
        Assert.assertEquals(calendar.get(Calendar.MONTH), 2);
        Assert.assertEquals(calendar.get(Calendar.DAY_OF_MONTH), 3);
        Assert.assertEquals(calendar.get(Calendar.HOUR), 3);
        Assert.assertEquals(calendar.get(Calendar.MINUTE), 5);
        Assert.assertEquals(calendar.get(Calendar.SECOND), 6);
        Assert.assertEquals(calendar.get(Calendar.MILLISECOND), 0);
    }

    @Test
    public void testFromDolphinConversionFixDateWithTimeZoneConversion() throws ValueConverterException {
        CalendarConverterFactory factory = new CalendarConverterFactory();
        Converter converter = factory.getConverterForType(Calendar.class);

        String input = "2017-03-03T03:05:06.000Z";

        Object converted = converter.convertFromDolphin(input);
        Assert.assertNotNull(converted);
        Assert.assertTrue(converted instanceof Calendar);

        Calendar calendar = (Calendar) converted;
        calendar.setTimeZone(TimeZone.getTimeZone("GMT+1"));

        Assert.assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("GMT+1"));
        Assert.assertEquals(calendar.get(Calendar.YEAR), 2017);
        Assert.assertEquals(calendar.get(Calendar.MONTH), 2);
        Assert.assertEquals(calendar.get(Calendar.DAY_OF_MONTH), 3);
        Assert.assertEquals(calendar.get(Calendar.HOUR), 4);
        Assert.assertEquals(calendar.get(Calendar.MINUTE), 5);
        Assert.assertEquals(calendar.get(Calendar.SECOND), 6);
        Assert.assertEquals(calendar.get(Calendar.MILLISECOND), 0);
    }
}

@@ -2620,32 +2620,83 @@
 egorianCalendar(
+TimeZone.getTimeZone(%22UTC%22));%0A        calendar.set(
 2017, 2, 3,4, 5,
@@ -3218,34 +3218,132 @@
 alendar(
-2017, 2, 3,4, 5, 6
+TimeZone.getTimeZone(%22UTC%22));%0A        calendar.set(2017, 2, 3,4, 5, 6);%0A        calendar.set(Calendar.MILLISECOND, 0
 );%0A     
@@ -3543,33 +3543,33 @@
 d, %222017-03-03T0
-3
+4
 :05:06.000Z%22);%0A 
@@ -3632,19 +3632,19 @@
 ixDateIn
-UTC
+Gmt
 () throw
@@ -3872,16 +3872,69 @@
 alendar(
+TimeZone.getTimeZone(%22GMT+1%22));%0A        calendar.set(
 2017, 2,
@@ -3970,44 +3970,32 @@
 .set
-TimeZone(TimeZone.getTimeZone(%22UTC%22)
+(Calendar.MILLISECOND, 0
 );%0A 
@@ -4199,33 +4199,33 @@
 d, %222017-03-03T0
-4
+3
 :05:06.000Z%22);%0A 

Test do not depend on system time zone