/*
 * Copyright (C) 2021 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.net.vcn;

import static com.android.internal.annotations.VisibleForTesting.Visibility;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.PersistableBundle;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

// TODO: Add documents
/** @hide */
public abstract class VcnUnderlyingNetworkPriority {
    /** @hide */
    protected static final int NETWORK_PRIORITY_TYPE_WIFI = 1;
    /** @hide */
    protected static final int NETWORK_PRIORITY_TYPE_CELL = 2;

    /** Denotes that any network quality is acceptable */
    public static final int NETWORK_QUALITY_ANY = 0;
    /** Denotes that network quality needs to be OK */
    public static final int NETWORK_QUALITY_OK = 100000;

    private static final SparseArray<String> NETWORK_QUALITY_TO_STRING_MAP = new SparseArray<>();

    static {
        NETWORK_QUALITY_TO_STRING_MAP.put(NETWORK_QUALITY_ANY, "NETWORK_QUALITY_ANY");
        NETWORK_QUALITY_TO_STRING_MAP.put(NETWORK_QUALITY_OK, "NETWORK_QUALITY_OK");
    }

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({NETWORK_QUALITY_OK, NETWORK_QUALITY_ANY})
    public @interface NetworkQuality {}

    private static final String NETWORK_PRIORITY_TYPE_KEY = "mNetworkPriorityType";
    private final int mNetworkPriorityType;

    /** @hide */
    protected static final String NETWORK_QUALITY_KEY = "mNetworkQuality";
    private final int mNetworkQuality;

    /** @hide */
    protected static final String ALLOW_METERED_KEY = "mAllowMetered";
    private final boolean mAllowMetered;

    /** @hide */
    protected VcnUnderlyingNetworkPriority(
            int networkPriorityType, int networkQuality, boolean allowMetered) {
        mNetworkPriorityType = networkPriorityType;
        mNetworkQuality = networkQuality;
        mAllowMetered = allowMetered;
    }

    private static void validateNetworkQuality(int networkQuality) {
        Preconditions.checkArgument(
                networkQuality == NETWORK_QUALITY_ANY || networkQuality == NETWORK_QUALITY_OK,
                "Invalid networkQuality:" + networkQuality);
    }

    /** @hide */
    protected void validate() {
        validateNetworkQuality(mNetworkQuality);
    }

    /** @hide */
    @NonNull
    @VisibleForTesting(visibility = Visibility.PROTECTED)
    public static VcnUnderlyingNetworkPriority fromPersistableBundle(
            @NonNull PersistableBundle in) {
        Objects.requireNonNull(in, "PersistableBundle is null");

        final int networkPriorityType = in.getInt(NETWORK_PRIORITY_TYPE_KEY);
        switch (networkPriorityType) {
            case NETWORK_PRIORITY_TYPE_WIFI:
                return VcnWifiUnderlyingNetworkPriority.fromPersistableBundle(in);
            case NETWORK_PRIORITY_TYPE_CELL:
                return VcnCellUnderlyingNetworkPriority.fromPersistableBundle(in);
            default:
                throw new IllegalArgumentException(
                        "Invalid networkPriorityType:" + networkPriorityType);
        }
    }

    /** @hide */
    @NonNull
    PersistableBundle toPersistableBundle() {
        final PersistableBundle result = new PersistableBundle();

        result.putInt(NETWORK_PRIORITY_TYPE_KEY, mNetworkPriorityType);
        result.putInt(NETWORK_QUALITY_KEY, mNetworkQuality);
        result.putBoolean(ALLOW_METERED_KEY, mAllowMetered);

        return result;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mNetworkPriorityType, mNetworkQuality, mAllowMetered);
    }

    @Override
    public boolean equals(@Nullable Object other) {
        if (!(other instanceof VcnUnderlyingNetworkPriority)) {
            return false;
        }

        final VcnUnderlyingNetworkPriority rhs = (VcnUnderlyingNetworkPriority) other;
        return mNetworkPriorityType == rhs.mNetworkPriorityType
                && mNetworkQuality == rhs.mNetworkQuality
                && mAllowMetered == rhs.mAllowMetered;
    }

    /** @hide */
    abstract void dumpTransportSpecificFields(IndentingPrintWriter pw);

    /**
     * Dumps the state of this record for logging and debugging purposes.
     *
     * @hide
     */
    public void dump(IndentingPrintWriter pw) {
        pw.println(this.getClass().getSimpleName() + ":");
        pw.increaseIndent();

        pw.println(
                "mNetworkQuality: "
                        + NETWORK_QUALITY_TO_STRING_MAP.get(
                                mNetworkQuality, "Invalid value " + mNetworkQuality));
        pw.println("mAllowMetered: " + mAllowMetered);
        dumpTransportSpecificFields(pw);

        pw.decreaseIndent();
    }

    /** Retrieve the required network quality. */
    @NetworkQuality
    public int getNetworkQuality() {
        return mNetworkQuality;
    }

    /** Return if a metered network is allowed. */
    public boolean allowMetered() {
        return mAllowMetered;
    }

    /**
     * This class is used to incrementally build VcnUnderlyingNetworkPriority objects.
     *
     * @param <T> The subclass to be built.
     */
    public abstract static class Builder<T extends Builder<T>> {
        /** @hide */
        protected int mNetworkQuality = NETWORK_QUALITY_ANY;
        /** @hide */
        protected boolean mAllowMetered = false;

        /** @hide */
        protected Builder() {}

        /**
         * Set the required network quality.
         *
         * @param networkQuality the required network quality. Defaults to NETWORK_QUALITY_ANY
         */
        @NonNull
        public T setNetworkQuality(@NetworkQuality int networkQuality) {
            validateNetworkQuality(networkQuality);

            mNetworkQuality = networkQuality;
            return self();
        }

        /**
         * Set if a metered network is allowed.
         *
         * @param allowMetered the flag to indicate if a metered network is allowed, defaults to
         *     {@code false}
         */
        @NonNull
        public T setAllowMetered(boolean allowMetered) {
            mAllowMetered = allowMetered;
            return self();
        }

        /** @hide */
        abstract T self();
    }
}
