/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 org.apache.johnzon.jsonb;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.StringReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbConfig;
import jakarta.json.bind.annotation.JsonbCreator;
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.json.bind.spi.JsonbProvider;

import org.apache.cxf.common.util.StringUtils;
import org.junit.Test;

public class JsonbTypesTest {
    @Test
    public void readAndWrite() throws Exception {
        final LocalDate localDate = LocalDate.of(2015, 1, 1);
        final LocalTime localTime = LocalTime.of(1, 2, 3);
        final LocalDateTime localDateTime = LocalDateTime.of(2015, 1, 1, 1, 1);
        final String expected = "{\"bigDecimal\":\"1.5\",\"bigInteger\":\"1\"," +
                "\"calendar\":\"2015-01-01T01:01:00Z[UTC]\",\"date\":\"2015-01-01T01:01:00Z[UTC]\"," +
                "\"duration\":\"PT30S\",\"gregorianCalendar\":\"2015-01-01T01:01:00Z[UTC]\"," +
                "\"instant\":\"2015-01-01T00:00:00Z\",\"localDate\":\"2015-01-01\"," +
                "\"localDateTime\":\"2015-01-01T01:01\",\"localTime\":\"01:02:03\"," +
                "\"offsetDateTime\":\"2015-01-01T01:01Z\",\"offsetTime\":\"01:01Z\"," +
                "\"optionalDouble\":3.4,\"optionalInt\":1,\"optionalLong\":2,\"optionalString\":\"yes\"," +
                "\"period\":\"P1M10D\",\"simpleTimeZone\":\"UTC\",\"timeZone\":\"UTC\"," +
                "\"uri\":\"http://localhost:2222\",\"url\":\"http://localhost:1111\"," +
                "\"zoneId\":\"UTC\",\"zoneOffset\":\"Z\"}";

        final Jsonb jsonb = newJsonb();

        final Types types = jsonb.fromJson(new StringReader(expected), Types.class);
        assertEquals("http://localhost:1111", types.url.toExternalForm());
        assertEquals("http://localhost:2222", types.uri.toASCIIString());
        assertEquals(Optional.of("yes"), types.optionalString);
        assertEquals(1, types.optionalInt.getAsInt());
        assertEquals(2, types.optionalLong.getAsLong());
        assertEquals(3.4, types.optionalDouble.getAsDouble(), 0.);
        assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), types.date.getTime());
        assertEquals(localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli(), types.calendar.getTime().getTime());
        assertEquals(localDateTime, types.localDateTime);
        assertEquals(localTime, types.localTime);
        assertEquals(localDate, types.localDate);
        assertEquals(OffsetDateTime.of(localDateTime, ZoneOffset.UTC), types.offsetDateTime);
        assertEquals(OffsetTime.of(localDateTime.toLocalTime(), ZoneOffset.UTC), types.offsetTime);
        assertEquals(TimeZone.getTimeZone("UTC"), types.timeZone);
        assertEquals(ZoneId.of("UTC"), types.zoneId);
        assertEquals(ZoneOffset.UTC, types.zoneOffset);
        assertEquals("UTC", types.simpleTimeZone.getID());
        assertEquals(0, types.simpleTimeZone.getRawOffset());
        assertEquals(TimeUnit.DAYS.toMillis(localDate.toEpochDay()), types.instant.toEpochMilli());
        assertEquals(Duration.of(30, ChronoUnit.SECONDS), types.duration);
        assertEquals(Period.of(0, 1, 10), types.period);
        assertEquals(BigInteger.valueOf(1), types.bigInteger);
        assertEquals(BigDecimal.valueOf(1.5), types.bigDecimal);

        assertEquals(expected, jsonb.toJson(types));

        jsonb.close();
    }

    @Test
    public void testReadAndWriteBigIntDecimalAsNumbers() throws Exception {
        final String expected = "{\"bigDecimal\":1.5,\"bigInteger\":1}";
        final Jsonb jsonb = newJsonb(
                new JsonbConfig()
                        .setProperty("johnzon.use-biginteger-stringadapter", false)
                        .setProperty("johnzon.use-bigdecimal-stringadapter", false));

        final Types types = jsonb.fromJson(new StringReader(expected), Types.class);
        assertEquals(BigInteger.valueOf(1), types.bigInteger);
        assertEquals(BigDecimal.valueOf(1.5), types.bigDecimal);

        assertEquals(expected, jsonb.toJson(types));

        jsonb.close();
    }

    @Test
    public void readAndWriteWithDateFormats() throws Exception {
        readAndWriteWithDateFormat(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"), "yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        readAndWriteWithDateFormat(DateTimeFormatter.ofPattern("yyyyMMdd+HHmmssZ"), "yyyyMMdd+HHmmssZ");
        readAndWriteWithDateFormat(DateTimeFormatter.ofPattern("yyyy-MM-dd"), "yyyy-MM-dd");
    }

    @Test
    public void testOptionalViaJsonbCreatorFullJson() {
        final Jsonb jsonb = newJsonb();
        final String json = "{\"intOptional\":4711,\"stringOptional\":\"testVal\"}";
        final OptionalTypes optionalTypes = jsonb.fromJson(json, OptionalTypes.class);
        assertNotNull(optionalTypes);
        assertEquals("testVal", optionalTypes.getOptionalString());
        assertEquals(4711, optionalTypes.getOptionalInt());
    }

    @Test
    public void testOptionalViaJsonbCreatorEmptyJson() {
        final Jsonb jsonb = newJsonb();
        final String json = "{ }";
        final OptionalTypes optionalTypes = jsonb.fromJson(json, OptionalTypes.class);
        assertNotNull(optionalTypes);
        assertEquals(OptionalTypes.EMPTY, optionalTypes.getOptionalString());
        assertEquals(-1, optionalTypes.getOptionalInt());
    }

    @Test
    public void testOptionalViaJsonbCreatorPartialJson() {
        final Jsonb jsonb = newJsonb();
        final String json = "{\"intOptional\":4711}";
        final OptionalTypes optionalTypes = jsonb.fromJson(json, OptionalTypes.class);
        assertNotNull(optionalTypes);
        assertEquals(OptionalTypes.EMPTY, optionalTypes.getOptionalString());
        assertEquals(4711, optionalTypes.getOptionalInt());
    }

    private void readAndWriteWithDateFormat(DateTimeFormatter dateTimeFormatter, String dateFormat) throws Exception {
        final LocalDate localDate = LocalDate.of(2015, 1, 1);
        final LocalDateTime localDateTime = LocalDateTime.of(2015, 1, 1, 1, 1);
        final ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("UTC"));
        final String expected = "{" +
            "\"calendar\":\"" + dateTimeFormatter.format(zonedDateTime) + "\"," +
            "\"date\":\"" + dateTimeFormatter.format(ZonedDateTime.ofInstant(localDateTime.toInstant(ZoneOffset.UTC), ZoneId.of("UTC"))) + "\"," +
            "\"gregorianCalendar\":\"" + dateTimeFormatter.format(zonedDateTime) + "\"," +
            "\"instant\":\"" + dateTimeFormatter.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(TimeUnit.DAYS.toMillis(localDate.toEpochDay())), ZoneId.of("UTC"))) + "\"," +
            "\"localDate\":\"" + dateTimeFormatter.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(TimeUnit.DAYS.toMillis(localDate.toEpochDay())), ZoneId.of("UTC"))) + "\"," +
            "\"localDateTime\":\"" + dateTimeFormatter.format(ZonedDateTime.ofInstant(localDateTime.toInstant(ZoneOffset.UTC), ZoneId.of("UTC"))) + "\"," +
            "\"offsetDateTime\":\"" + dateTimeFormatter.format(ZonedDateTime.ofInstant(OffsetDateTime.of(localDateTime, ZoneOffset.UTC).toInstant(), ZoneId.of("UTC"))) + "\"" +
            "}";

        final Jsonb jsonb = newJsonb(dateFormat);
        
        final DateTypes types = jsonb.fromJson(new StringReader(expected), DateTypes.class);
        assertEquals(localDate, types.localDate);
        assertEquals(expected, jsonb.toJson(types));

        jsonb.close();
    }
    
    private static Jsonb newJsonb() {
        return newJsonb((String) null);
    }
    
    private static Jsonb newJsonb(String dateFormat) {
        JsonbConfig jsonbConfig = new JsonbConfig();
        if (!StringUtils.isEmpty(dateFormat)){
            jsonbConfig.withDateFormat(dateFormat, Locale.getDefault());
        }

        return newJsonb(jsonbConfig.setProperty("johnzon.attributeOrder", new Comparator<String>() {
            @Override
            public int compare(final String o1, final String o2) {
                return o1.compareTo(o2);
            }
        }));
    }

    private static Jsonb newJsonb(JsonbConfig jsonbConfig) {
        return JsonbProvider.provider().create().withConfig(jsonbConfig).build();
    }

    public static class Types {
        private URL url;
        private URI uri;
        private Optional<String> optionalString;
        private OptionalInt optionalInt;
        private OptionalLong optionalLong;
        private OptionalDouble optionalDouble;
        private Date date;
        private Calendar calendar;
        private GregorianCalendar gregorianCalendar;
        private TimeZone timeZone;
        private ZoneId zoneId;
        private ZoneOffset zoneOffset;
        private SimpleTimeZone simpleTimeZone;
        private Instant instant;
        private Duration duration;
        private Period period;
        private LocalDateTime localDateTime;
        private LocalTime localTime;
        private LocalDate localDate;
        private OffsetDateTime offsetDateTime;
        private OffsetTime offsetTime;
        private BigInteger bigInteger;
        private BigDecimal bigDecimal;

        public LocalTime getLocalTime() {
            return localTime;
        }

        public void setLocalTime(final LocalTime localTime) {
            this.localTime = localTime;
        }

        public URL getUrl() {
            return url;
        }

        public void setUrl(URL url) {
            this.url = url;
        }

        public URI getUri() {
            return uri;
        }

        public void setUri(URI uri) {
            this.uri = uri;
        }

        public Optional<String> getOptionalString() {
            return optionalString;
        }

        public void setOptionalString(Optional<String> optionalString) {
            this.optionalString = optionalString;
        }

        public OptionalInt getOptionalInt() {
            return optionalInt;
        }

        public void setOptionalInt(OptionalInt optionalInt) {
            this.optionalInt = optionalInt;
        }

        public OptionalLong getOptionalLong() {
            return optionalLong;
        }

        public void setOptionalLong(OptionalLong optionalLong) {
            this.optionalLong = optionalLong;
        }

        public OptionalDouble getOptionalDouble() {
            return optionalDouble;
        }

        public void setOptionalDouble(OptionalDouble optionalDouble) {
            this.optionalDouble = optionalDouble;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public Calendar getCalendar() {
            return calendar;
        }

        public void setCalendar(Calendar calendar) {
            this.calendar = calendar;
        }

        public GregorianCalendar getGregorianCalendar() {
            return gregorianCalendar;
        }

        public void setGregorianCalendar(GregorianCalendar gregorianCalendar) {
            this.gregorianCalendar = gregorianCalendar;
        }

        public TimeZone getTimeZone() {
            return timeZone;
        }

        public void setTimeZone(TimeZone timeZone) {
            this.timeZone = timeZone;
        }

        public ZoneId getZoneId() {
            return zoneId;
        }

        public void setZoneId(ZoneId zoneId) {
            this.zoneId = zoneId;
        }

        public ZoneOffset getZoneOffset() {
            return zoneOffset;
        }

        public void setZoneOffset(ZoneOffset zoneOffset) {
            this.zoneOffset = zoneOffset;
        }

        public SimpleTimeZone getSimpleTimeZone() {
            return simpleTimeZone;
        }

        public void setSimpleTimeZone(SimpleTimeZone simpleTimeZone) {
            this.simpleTimeZone = simpleTimeZone;
        }

        public Instant getInstant() {
            return instant;
        }

        public void setInstant(Instant instant) {
            this.instant = instant;
        }

        public Duration getDuration() {
            return duration;
        }

        public void setDuration(Duration duration) {
            this.duration = duration;
        }

        public Period getPeriod() {
            return period;
        }

        public void setPeriod(Period period) {
            this.period = period;
        }

        public LocalDateTime getLocalDateTime() {
            return localDateTime;
        }

        public void setLocalDateTime(LocalDateTime localDateTime) {
            this.localDateTime = localDateTime;
        }

        public LocalDate getLocalDate() {
            return localDate;
        }

        public void setLocalDate(LocalDate localDate) {
            this.localDate = localDate;
        }

        public OffsetDateTime getOffsetDateTime() {
            return offsetDateTime;
        }

        public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
            this.offsetDateTime = offsetDateTime;
        }

        public OffsetTime getOffsetTime() {
            return offsetTime;
        }

        public void setOffsetTime(OffsetTime offsetTime) {
            this.offsetTime = offsetTime;
        }

        public BigInteger getBigInteger() {
            return bigInteger;
        }

        public void setBigInteger(BigInteger bigInteger) {
            this.bigInteger = bigInteger;
        }

        public BigDecimal getBigDecimal() {
            return bigDecimal;
        }

        public void setBigDecimal(BigDecimal bigDecimal) {
            this.bigDecimal = bigDecimal;
        }

        @Override
        public boolean equals(final Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            final Types types = Types.class.cast(o);
            return Objects.equals(url, types.url) &&
                Objects.equals(uri, types.uri) &&
                Objects.equals(optionalString, types.optionalString) &&
                Objects.equals(optionalInt, types.optionalInt) &&
                Objects.equals(optionalLong, types.optionalLong) &&
                Objects.equals(optionalDouble, types.optionalDouble) &&
                Objects.equals(date, types.date) &&
                Objects.equals(calendar, types.calendar) &&
                Objects.equals(gregorianCalendar, types.gregorianCalendar) &&
                Objects.equals(timeZone, types.timeZone) &&
                Objects.equals(zoneId, types.zoneId) &&
                Objects.equals(zoneOffset, types.zoneOffset) &&
                Objects.equals(simpleTimeZone, types.simpleTimeZone) &&
                Objects.equals(instant, types.instant) &&
                Objects.equals(duration, types.duration) &&
                Objects.equals(period, types.period) &&
                Objects.equals(localDateTime, types.localDateTime) &&
                Objects.equals(localDate, types.localDate) &&
                Objects.equals(offsetDateTime, types.offsetDateTime) &&
                Objects.equals(offsetTime, types.offsetTime) &&
                Objects.equals(bigInteger, types.bigInteger) &&
                Objects.equals(bigDecimal, types.bigDecimal);
        }

        @Override
        public int hashCode() {
            return Objects.hash(
                url, uri, optionalString, optionalInt, optionalLong, optionalDouble, date,
                calendar, gregorianCalendar, timeZone, zoneId, zoneOffset, simpleTimeZone, instant, duration,
                period, localDateTime, localDate, offsetDateTime, offsetTime, bigInteger, bigDecimal);
        }
    }

    public static class DateTypes {
        private Date date;
        private Calendar calendar;
        private GregorianCalendar gregorianCalendar;
        private Instant instant;
        private LocalDateTime localDateTime;
        private LocalDate localDate;
        private OffsetDateTime offsetDateTime;


        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public Calendar getCalendar() {
            return calendar;
        }

        public void setCalendar(Calendar calendar) {
            this.calendar = calendar;
        }

        public GregorianCalendar getGregorianCalendar() {
            return gregorianCalendar;
        }

        public void setGregorianCalendar(GregorianCalendar gregorianCalendar) {
            this.gregorianCalendar = gregorianCalendar;
        }

        public Instant getInstant() {
            return instant;
        }

        public void setInstant(Instant instant) {
            this.instant = instant;
        }

        public LocalDateTime getLocalDateTime() {
            return localDateTime;
        }

        public void setLocalDateTime(LocalDateTime localDateTime) {
            this.localDateTime = localDateTime;
        }

        public LocalDate getLocalDate() {
            return localDate;
        }

        public void setLocalDate(LocalDate localDate) {
            this.localDate = localDate;
        }

        public OffsetDateTime getOffsetDateTime() {
            return offsetDateTime;
        }

        public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
            this.offsetDateTime = offsetDateTime;
        }


        @Override
        public boolean equals(final Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            final Types types = Types.class.cast(o);
            return 
                Objects.equals(date, types.date) &&
                Objects.equals(calendar, types.calendar) &&
                Objects.equals(gregorianCalendar, types.gregorianCalendar) &&
                Objects.equals(instant, types.instant) &&
                Objects.equals(localDateTime, types.localDateTime) &&
                Objects.equals(localDate, types.localDate) &&
                Objects.equals(offsetDateTime, types.offsetDateTime);
        }

        @Override
        public int hashCode() {
            return Objects.hash(
                date, calendar, gregorianCalendar, instant, localDateTime, localDate, offsetDateTime);
        }
    }

    public static class OptionalTypes {
        public final static String EMPTY = "    ";
        private final String optionalString;
        private final int optionalInt;

        public OptionalTypes(String optionalString, int optionalInt) {
            this.optionalString = optionalString;
            this.optionalInt = optionalInt;
        }

        @JsonbCreator
        public static OptionalTypes init(@JsonbProperty("stringOptional") Optional<String> stringOptional,
                                         @JsonbProperty("intOptional") OptionalInt intOptional) {
            return new OptionalTypes(
                    stringOptional.orElse(EMPTY),
                    intOptional.orElse(-1));
        }

        public String getOptionalString() {
            return optionalString;
        }

        public int getOptionalInt() {
            return optionalInt;
        }
    }
}
