/*
 * Copyright (C) 2017 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.bluetooth;

import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Arrays;
import java.util.Objects;

/**
 * Represents the codec status (configuration and capability) for a Bluetooth
 * A2DP source device.
 *
 * {@see BluetoothA2dp}
 *
 * {@hide}
 */
public final class BluetoothCodecStatus implements Parcelable {
    /**
     * Extra for the codec configuration intents of the individual profiles.
     *
     * This extra represents the current codec status of the A2DP
     * profile.
     */
    @UnsupportedAppUsage
    public static final String EXTRA_CODEC_STATUS =
            "android.bluetooth.codec.extra.CODEC_STATUS";

    private final BluetoothCodecConfig mCodecConfig;
    private final BluetoothCodecConfig[] mCodecsLocalCapabilities;
    private final BluetoothCodecConfig[] mCodecsSelectableCapabilities;

    public BluetoothCodecStatus(BluetoothCodecConfig codecConfig,
            BluetoothCodecConfig[] codecsLocalCapabilities,
            BluetoothCodecConfig[] codecsSelectableCapabilities) {
        mCodecConfig = codecConfig;
        mCodecsLocalCapabilities = codecsLocalCapabilities;
        mCodecsSelectableCapabilities = codecsSelectableCapabilities;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof BluetoothCodecStatus) {
            BluetoothCodecStatus other = (BluetoothCodecStatus) o;
            return (Objects.equals(other.mCodecConfig, mCodecConfig)
                    && sameCapabilities(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
                    && sameCapabilities(other.mCodecsSelectableCapabilities,
                    mCodecsSelectableCapabilities));
        }
        return false;
    }

    /**
     * Checks whether two arrays of capabilities contain same capabilities.
     * The order of the capabilities in each array is ignored.
     *
     * @param c1 the first array of capabilities to compare
     * @param c2 the second array of capabilities to compare
     * @return true if both arrays contain same capabilities
     */
    private static boolean sameCapabilities(BluetoothCodecConfig[] c1,
                                            BluetoothCodecConfig[] c2) {
        if (c1 == null) {
            return (c2 == null);
        }
        if (c2 == null) {
            return false;
        }
        if (c1.length != c2.length) {
            return false;
        }
        return Arrays.asList(c1).containsAll(Arrays.asList(c2));
    }

    @Override
    public int hashCode() {
        return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,
                mCodecsLocalCapabilities);
    }

    @Override
    public String toString() {
        return "{mCodecConfig:" + mCodecConfig
                + ",mCodecsLocalCapabilities:" + Arrays.toString(mCodecsLocalCapabilities)
                + ",mCodecsSelectableCapabilities:" + Arrays.toString(mCodecsSelectableCapabilities)
                + "}";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<BluetoothCodecStatus> CREATOR =
            new Parcelable.Creator<BluetoothCodecStatus>() {
                public BluetoothCodecStatus createFromParcel(Parcel in) {
                    final BluetoothCodecConfig codecConfig = in.readTypedObject(
                            BluetoothCodecConfig.CREATOR);
                    final BluetoothCodecConfig[] codecsLocalCapabilities = in.createTypedArray(
                            BluetoothCodecConfig.CREATOR);
                    final BluetoothCodecConfig[] codecsSelectableCapabilities = in.createTypedArray(
                            BluetoothCodecConfig.CREATOR);

                    return new BluetoothCodecStatus(codecConfig,
                            codecsLocalCapabilities,
                            codecsSelectableCapabilities);
                }

                public BluetoothCodecStatus[] newArray(int size) {
                    return new BluetoothCodecStatus[size];
                }
            };

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeTypedObject(mCodecConfig, 0);
        out.writeTypedArray(mCodecsLocalCapabilities, 0);
        out.writeTypedArray(mCodecsSelectableCapabilities, 0);
    }

    /**
     * Gets the current codec configuration.
     *
     * @return the current codec configuration
     */
    @UnsupportedAppUsage
    public BluetoothCodecConfig getCodecConfig() {
        return mCodecConfig;
    }

    /**
     * Gets the codecs local capabilities.
     *
     * @return an array with the codecs local capabilities
     */
    @UnsupportedAppUsage
    public BluetoothCodecConfig[] getCodecsLocalCapabilities() {
        return mCodecsLocalCapabilities;
    }

    /**
     * Gets the codecs selectable capabilities.
     *
     * @return an array with the codecs selectable capabilities
     */
    @UnsupportedAppUsage
    public BluetoothCodecConfig[] getCodecsSelectableCapabilities() {
        return mCodecsSelectableCapabilities;
    }
}
