/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 android.timezone;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.icu.util.TimeZone;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * Information about a country's time zones.
 *
 * @hide
 */
public final class CountryTimeZones {

    /**
     * A mapping to a time zone ID with some associated metadata.
     *
     * @hide
     */
    public static final class TimeZoneMapping {

        @NonNull
        private libcore.timezone.CountryTimeZones.TimeZoneMapping mDelegate;

        TimeZoneMapping(libcore.timezone.CountryTimeZones.TimeZoneMapping delegate) {
            this.mDelegate = Objects.requireNonNull(delegate);
        }

        /**
         * Returns the ID for this mapping. The ID is a tzdb time zone identifier like
         * "America/Los_Angeles" that can be used with methods such as {@link
         * TimeZone#getFrozenTimeZone(String)}. See {@link #getTimeZone()} which returns a frozen
         * {@link TimeZone} object.
         */
        @NonNull
        public String getTimeZoneId() {
            return mDelegate.getTimeZoneId();
        }

        /**
         * Returns a frozen {@link TimeZone} object for this mapping.
         */
        @NonNull
        public TimeZone getTimeZone() {
            return mDelegate.getTimeZone();
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            TimeZoneMapping that = (TimeZoneMapping) o;
            return this.mDelegate.equals(that.mDelegate);
        }

        @Override
        public int hashCode() {
            return this.mDelegate.hashCode();
        }

        @Override
        public String toString() {
            return mDelegate.toString();
        }
    }

    /**
     * The result of lookup up a time zone using offset information (and possibly more).
     *
     * @hide
     */
    public static final class OffsetResult {

        private final TimeZone mTimeZone;
        private final boolean mIsOnlyMatch;

        /** Creates an instance with the supplied information. */
        public OffsetResult(@NonNull TimeZone timeZone, boolean isOnlyMatch) {
            mTimeZone = Objects.requireNonNull(timeZone);
            mIsOnlyMatch = isOnlyMatch;
        }

        /**
         * Returns a time zone that matches the supplied criteria.
         */
        @NonNull
        public TimeZone getTimeZone() {
            return mTimeZone;
        }

        /**
         * Returns {@code true} if there is only one matching time zone for the supplied criteria.
         */
        public boolean isOnlyMatch() {
            return mIsOnlyMatch;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            OffsetResult that = (OffsetResult) o;
            return mIsOnlyMatch == that.mIsOnlyMatch
                    && mTimeZone.getID().equals(that.mTimeZone.getID());
        }

        @Override
        public int hashCode() {
            return Objects.hash(mTimeZone, mIsOnlyMatch);
        }

        @Override
        public String toString() {
            return "OffsetResult{"
                    + "mTimeZone(ID)=" + mTimeZone.getID()
                    + ", mIsOnlyMatch=" + mIsOnlyMatch
                    + '}';
        }
    }

    @NonNull
    private final libcore.timezone.CountryTimeZones mDelegate;

    CountryTimeZones(libcore.timezone.CountryTimeZones delegate) {
        mDelegate = delegate;
    }

    /**
     * Returns true if the ISO code for the country is a case-insensitive match for the one
     * supplied.
     */
    public boolean matchesCountryCode(@NonNull String countryIso) {
        return mDelegate.isForCountryCode(countryIso);
    }

    /**
     * Returns the default time zone ID for the country. Can return {@code null} in cases when no
     * data is available or the time zone ID was not recognized.
     */
    @Nullable
    public String getDefaultTimeZoneId() {
        return mDelegate.getDefaultTimeZoneId();
    }

    /**
     * Returns the default time zone for the country. Can return {@code null} in cases when no data
     * is available or the time zone ID was not recognized.
     */
    @Nullable
    public TimeZone getDefaultTimeZone() {
        return mDelegate.getDefaultTimeZone();
    }

    /**
     * Qualifier for a country's default time zone. {@code true} indicates that the country's
     * default time zone would be a good choice <em>generally</em> when there's no UTC offset
     * information available. This will only be {@code true} in countries with multiple zones where
     * a large majority of the population is covered by only one of them.
     */
    public boolean isDefaultTimeZoneBoosted() {
        return mDelegate.isDefaultTimeZoneBoosted();
    }

    /**
     * Returns {@code true} if the country has at least one time zone that uses UTC at the given
     * time. This is an efficient check when trying to validate received UTC offset information.
     * For example, there are situations when a detected zero UTC offset cannot be distinguished
     * from "no information available" or a corrupted signal. This method is useful because checking
     * offset information for large countries is relatively expensive but it is generally only the
     * countries close to the prime meridian that use UTC at <em>any</em> time of the year.
     *
     * @param whenMillis the time the offset information is for in milliseconds since the beginning
     *     of the Unix epoch
     */
    public boolean hasUtcZone(long whenMillis) {
        return mDelegate.hasUtcZone(whenMillis);
    }

    /**
     * Returns a time zone for the country, if there is one, that matches the supplied properties.
     * If there are multiple matches and the {@code bias} is one of them then it is returned,
     * otherwise an arbitrary match is returned based on the {@link
     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
     *
     * @param whenMillis the UTC time to match against
     * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
     * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
     * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
     *     {@code false} means not DST
     * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
     *     there is no match
     */
    @Nullable
    public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias,
            int totalOffsetMillis, boolean isDst) {
        libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
                mDelegate.lookupByOffsetWithBias(
                        whenMillis, bias, totalOffsetMillis, isDst);
        return delegateOffsetResult == null ? null :
                new OffsetResult(
                        delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
    }

    /**
     * Returns a time zone for the country, if there is one, that matches the supplied properties.
     * If there are multiple matches and the {@code bias} is one of them then it is returned,
     * otherwise an arbitrary match is returned based on the {@link
     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
     *
     * @param whenMillis the UTC time to match against
     * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
     * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
     * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
     *     there is no match
     */
    @Nullable
    public OffsetResult lookupByOffsetWithBias(long whenMillis, @Nullable TimeZone bias,
            int totalOffsetMillis) {
        libcore.timezone.CountryTimeZones.OffsetResult delegateOffsetResult =
                mDelegate.lookupByOffsetWithBias(whenMillis, bias, totalOffsetMillis);
        return delegateOffsetResult == null ? null :
                new OffsetResult(
                        delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
    }

    /**
     * Returns an immutable, ordered list of time zone mappings for the country in an undefined but
     * "priority" order, filtered so that only "effective" time zone IDs are returned. An
     * "effective" time zone is one that differs from another time zone used in the country after
     * {@code whenMillis}. The list can be empty if there were no zones configured or the configured
     * zone IDs were not recognized.
     */
    @NonNull
    public List<TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long whenMillis) {
        List<libcore.timezone.CountryTimeZones.TimeZoneMapping> delegateList =
                mDelegate.getEffectiveTimeZoneMappingsAt(whenMillis);

        List<TimeZoneMapping> toReturn = new ArrayList<>(delegateList.size());
        for (libcore.timezone.CountryTimeZones.TimeZoneMapping delegateMapping : delegateList) {
            toReturn.add(new TimeZoneMapping(delegateMapping));
        }
        return Collections.unmodifiableList(toReturn);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        CountryTimeZones that = (CountryTimeZones) o;
        return mDelegate.equals(that.mDelegate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mDelegate);
    }

    @Override
    public String toString() {
        return mDelegate.toString();
    }
}
