/*
 * 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.sis.xml.bind.gts;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;
import javax.xml.datatype.Duration;
import javax.xml.datatype.DatatypeConfigurationException;
import jakarta.xml.bind.annotation.XmlElement;
import org.apache.sis.xml.bind.Context;
import org.apache.sis.xml.privy.XmlUtilities;
import org.apache.sis.xml.bind.gco.PropertyType;
import org.apache.sis.util.resources.Errors;


/**
 * Wraps a {@code gts:TM_Duration} element.
 *
 * @author  Guilhem Legal (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @author  Cullen Rombach (Image Matters)
 */
public class TM_Duration extends PropertyType<TM_Duration, TemporalAmount> {
    /**
     * Empty constructor for JAXB.
     */
    public TM_Duration() {
    }

    /**
     * Wraps a duration value at marshalling-time.
     *
     * @param  metadata  the metadata value to marshal.
     */
    private TM_Duration(final TemporalAmount metadata) {
        super(metadata);
    }

    /**
     * Returns the duration value wrapped by a {@code gts:TM_Duration} element.
     *
     * @param  value  the value to marshal.
     * @return the adapter which wraps the metadata value.
     */
    @Override
    protected TM_Duration wrap(final TemporalAmount value) {
        return new TM_Duration(value);
    }

    /**
     * Returns the interface which is bound by this adapter.
     *
     * @return {@code TemporalAmount.class}
     */
    @Override
    protected final Class<TemporalAmount> getBoundType() {
        return TemporalAmount.class;
    }

    /**
     * Returns the {@code Duration} generated from the metadata value.
     * This method is systematically called at marshalling time by JAXB.
     *
     * @return the time period, or {@code null}.
     */
    @XmlElement(name = "TM_Duration")
    public final Duration getElement() {
        @SuppressWarnings("LocalVariableHidesMemberVariable")
        final TemporalAmount metadata = this.metadata;
        if (metadata != null) try {
            BigInteger years   = null;
            BigInteger months  = null;
            BigInteger days    = null;
            BigInteger hours   = null;
            BigInteger minutes = null;
            BigDecimal seconds = null;
            for (TemporalUnit unit : metadata.getUnits()) {
                if (unit instanceof ChronoUnit) {
                    final BigInteger value = BigInteger.valueOf(metadata.get(unit));
                    switch ((ChronoUnit) unit) {
                        case YEARS:   years   = value; continue;
                        case MONTHS:  months  = value; continue;
                        case DAYS:    days    = value; continue;
                        case HOURS:   hours   = value; continue;
                        case MINUTES: minutes = value; continue;
                        case SECONDS: seconds = new BigDecimal(value); continue;
                        case MILLIS:  seconds = addSeconds(seconds, value, 1000); continue;
                        case MICROS:  seconds = addSeconds(seconds, value, 1_000_000); continue;
                        case NANOS:   seconds = addSeconds(seconds, value, 1_000_000_000); continue;
                    }
                }
                Context.warningOccured(Context.current(), TM_Duration.class, "getElement",
                                       Errors.class, Errors.Keys.UnsupportedType_1, unit);
                return null;
            }
            return XmlUtilities.getDatatypeFactory().newDuration(true, years, months, days, hours, minutes, seconds);
        } catch (DatatypeConfigurationException e) {
            Context.warningOccured(Context.current(), TM_Duration.class, "getElement", e, true);
        }
        return null;
    }

    /**
     * Returns <var>current</var> + (<var>numerator</var> / <var>denominator</var>) in seconds.
     * If {@code current} is {@code null}, then it is considered zero.
     *
     * @param  current      the value to add to in number of seconds, or {@code null} if not yet defined.
     * @param  numerator    numerator of the number of seconds to add.
     * @param  denominator  denominator of the number of seconds to add.
     * @return return of the addition, or {@code null} if none.
     */
    private static BigDecimal addSeconds(final BigDecimal current, final BigInteger numerator, final int denominator) {
        if (BigInteger.ZERO.equals(numerator)) {
            return current;
        }
        BigDecimal toAdd = new BigDecimal(numerator).divide(BigDecimal.valueOf(denominator));
        return (current != null) ? current.add(toAdd) : toAdd;
    }

    /**
     * Sets the value from the {@code Duration}.
     * This method is called at unmarshalling time by JAXB.
     *
     * @param  duration  the value to set.
     */
    public void setElement(final Duration duration) {
        if (duration != null) {
            int years  = duration.getYears();       // 0 if not present.
            int months = duration.getMonths();
            int days   = duration.getDays();
            if ((years | months | days) != 0) {
                metadata = Period.of(years, months, days);
            } else {
                int hours   = duration.getHours();
                int minutes = duration.getMinutes();
                int seconds = duration.getSeconds();
                if ((hours | minutes | seconds) != 0) {
                    metadata = java.time.Duration.ofSeconds(((hours * 24L) + minutes)*60 + seconds);
                }
            }
        }
    }

    /**
     * Wraps the value only if marshalling an element from the ISO 19115:2014 metadata model.
     * Otherwise (i.e. if marshalling according legacy ISO 19115:2003 model), omits the element.
     */
    public static final class Since2014 extends TM_Duration {
        /** Empty constructor used only by JAXB. */
        public Since2014() {
        }

        /**
         * Wraps the given value in an ISO 19115-3 element, unless we are marshalling an older document.
         *
         * @return a non-null value only if marshalling ISO 19115-3 or newer.
         */
        @Override protected TM_Duration wrap(final TemporalAmount value) {
            return accept2014() ? super.wrap(value) : null;
        }
    }
}
