/*
 * 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.sling.api.wrappers.impl;

import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.osgi.util.converter.ConversionException;
import org.osgi.util.converter.Converter;
import org.osgi.util.converter.Converters;
import org.osgi.util.converter.TypeRule;

/**
 * Converts objects to specific types.
 */
public final class ObjectConverter {

    private ObjectConverter() {
    }

    private static Converter converter;

    private static Converter getConverter() {
        // TODO at some point it may be practical to have TypeRules as OSGI services to
        // add more complex conversions much in the way that adaptTo has evolved
        if (converter == null) {
            synchronized (ObjectConverter.class) {
                if (converter == null) {
                    converter = Converters.newConverterBuilder()
                            .rule(new TypeRule<String, Calendar>(String.class, Calendar.class,
                                    ObjectConverter::toCalendar))
                            .rule(new TypeRule<Date, Calendar>(Date.class, Calendar.class,
                                    ObjectConverter::toCalendar))
                            .rule(new TypeRule<String, Date>(String.class, Date.class, ObjectConverter::toDate))
                            .rule(new TypeRule<Calendar, String>(Calendar.class, String.class,
                                    ObjectConverter::toString))
                            .rule(new TypeRule<Date, String>(Date.class, String.class, ObjectConverter::toString))
                            .rule(new TypeRule<Calendar, Date>(Calendar.class, Date.class,
                                    ObjectConverter::toDate))
                            .rule(new TypeRule<>(Calendar.class, ZonedDateTime.class, ObjectConverter::toZonedDateTime))
                            .rule(new TypeRule<ZonedDateTime, Calendar>(ZonedDateTime.class, Calendar.class, ObjectConverter::toCalendar))
                            .rule(new TypeRule<ZonedDateTime, String>(ZonedDateTime.class, String.class, ObjectConverter::toString))
                            .build();
                }
            }
        }
        return converter;
    }

    private static String toString(ZonedDateTime zonedDateTime) {
        return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(zonedDateTime);
    }

    private static Calendar toCalendar(ZonedDateTime zonedDateTime) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(zonedDateTime.getOffset()));
        calendar.setTimeInMillis(zonedDateTime.toInstant().toEpochMilli());
        return calendar;
    }

    private static ZonedDateTime toZonedDateTime(Calendar calendar) {
        return ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId().normalized());
    }

    private static String toString(Calendar cal) {
        return cal.toInstant().toString();
    }

    private static String toString(Date cal) {
        return cal.toInstant().toString();
    }

    private static Calendar toCalendar(String date) {
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(date, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
        return toCalendar(zonedDateTime);
    }

    private static Calendar toCalendar(Date date) {
        Calendar response = Calendar.getInstance();
        response.setTime(date);
        return response;
    }

    private static Date toDate(String date) {
        return Date.from(Instant.parse(date));
    }

    private static Date toDate(Calendar cal) {
        return cal.getTime();
    }

    /**
     * Converts the object to the given type.
     * 
     * @param obj
     *            object
     * @param type
     *            type
     * @param <T>
     *            Target type
     * @return the converted object
     */
    public static <T> T convert(Object obj, Class<T> type) {
        if (obj == null) {
            return null;
        }
        try {
            return getConverter().convert(obj).to(type);
        } catch (ConversionException ce) {
            return null;
        }
    }

}
