/*
 * Copyright (C) 2016 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.IntDef;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;

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

/**
 * Represents the codec configuration for a Bluetooth A2DP source device.
 *
 * {@see BluetoothA2dp}
 *
 * {@hide}
 */
public final class BluetoothCodecConfig implements Parcelable {
    // Add an entry for each source codec here.
    // NOTE: The values should be same as those listed in the following file:
    //   hardware/libhardware/include/hardware/bt_av.h

    /** @hide */
    @IntDef(prefix = "SOURCE_CODEC_TYPE_", value = {
            SOURCE_CODEC_TYPE_SBC,
            SOURCE_CODEC_TYPE_AAC,
            SOURCE_CODEC_TYPE_APTX,
            SOURCE_CODEC_TYPE_APTX_HD,
            SOURCE_CODEC_TYPE_LDAC,
            SOURCE_CODEC_TYPE_MAX,
            SOURCE_CODEC_TYPE_INVALID
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SourceCodecType {}

    public static final int SOURCE_CODEC_TYPE_SBC = 0;

    public static final int SOURCE_CODEC_TYPE_AAC = 1;

    public static final int SOURCE_CODEC_TYPE_APTX = 2;

    public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;

    public static final int SOURCE_CODEC_TYPE_LDAC = 4;

    public static final int SOURCE_CODEC_TYPE_MAX = 5;


    public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;

    /** @hide */
    @IntDef(prefix = "CODEC_PRIORITY_", value = {
            CODEC_PRIORITY_DISABLED,
            CODEC_PRIORITY_DEFAULT,
            CODEC_PRIORITY_HIGHEST
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface CodecPriority {}

    public static final int CODEC_PRIORITY_DISABLED = -1;

    public static final int CODEC_PRIORITY_DEFAULT = 0;

    public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;


    /** @hide */
    @IntDef(prefix = "SAMPLE_RATE_", value = {
            SAMPLE_RATE_NONE,
            SAMPLE_RATE_44100,
            SAMPLE_RATE_48000,
            SAMPLE_RATE_88200,
            SAMPLE_RATE_96000,
            SAMPLE_RATE_176400,
            SAMPLE_RATE_192000
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SampleRate {}

    public static final int SAMPLE_RATE_NONE = 0;

    public static final int SAMPLE_RATE_44100 = 0x1 << 0;

    public static final int SAMPLE_RATE_48000 = 0x1 << 1;

    public static final int SAMPLE_RATE_88200 = 0x1 << 2;

    public static final int SAMPLE_RATE_96000 = 0x1 << 3;

    public static final int SAMPLE_RATE_176400 = 0x1 << 4;

    public static final int SAMPLE_RATE_192000 = 0x1 << 5;


    /** @hide */
    @IntDef(prefix = "BITS_PER_SAMPLE_", value = {
            BITS_PER_SAMPLE_NONE,
            BITS_PER_SAMPLE_16,
            BITS_PER_SAMPLE_24,
            BITS_PER_SAMPLE_32
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BitsPerSample {}

    public static final int BITS_PER_SAMPLE_NONE = 0;

    public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;

    public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;

    public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;


    /** @hide */
    @IntDef(prefix = "CHANNEL_MODE_", value = {
            CHANNEL_MODE_NONE,
            CHANNEL_MODE_MONO,
            CHANNEL_MODE_STEREO
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ChannelMode {}

    public static final int CHANNEL_MODE_NONE = 0;

    public static final int CHANNEL_MODE_MONO = 0x1 << 0;

    public static final int CHANNEL_MODE_STEREO = 0x1 << 1;

    private final @SourceCodecType int mCodecType;
    private @CodecPriority int mCodecPriority;
    private final @SampleRate int mSampleRate;
    private final @BitsPerSample int mBitsPerSample;
    private final @ChannelMode int mChannelMode;
    private final long mCodecSpecific1;
    private final long mCodecSpecific2;
    private final long mCodecSpecific3;
    private final long mCodecSpecific4;

    public BluetoothCodecConfig(@SourceCodecType int codecType, @CodecPriority int codecPriority,
            @SampleRate int sampleRate, @BitsPerSample int bitsPerSample,
            @ChannelMode int channelMode, long codecSpecific1,
            long codecSpecific2, long codecSpecific3,
            long codecSpecific4) {
        mCodecType = codecType;
        mCodecPriority = codecPriority;
        mSampleRate = sampleRate;
        mBitsPerSample = bitsPerSample;
        mChannelMode = channelMode;
        mCodecSpecific1 = codecSpecific1;
        mCodecSpecific2 = codecSpecific2;
        mCodecSpecific3 = codecSpecific3;
        mCodecSpecific4 = codecSpecific4;
    }

    public BluetoothCodecConfig(@SourceCodecType int codecType) {
        mCodecType = codecType;
        mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
        mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE;
        mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE;
        mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE;
        mCodecSpecific1 = 0;
        mCodecSpecific2 = 0;
        mCodecSpecific3 = 0;
        mCodecSpecific4 = 0;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof BluetoothCodecConfig) {
            BluetoothCodecConfig other = (BluetoothCodecConfig) o;
            return (other.mCodecType == mCodecType
                    && other.mCodecPriority == mCodecPriority
                    && other.mSampleRate == mSampleRate
                    && other.mBitsPerSample == mBitsPerSample
                    && other.mChannelMode == mChannelMode
                    && other.mCodecSpecific1 == mCodecSpecific1
                    && other.mCodecSpecific2 == mCodecSpecific2
                    && other.mCodecSpecific3 == mCodecSpecific3
                    && other.mCodecSpecific4 == mCodecSpecific4);
        }
        return false;
    }

    /**
     * Returns a hash based on the config values
     *
     * @return a hash based on the config values
     * @hide
     */
    @Override
    public int hashCode() {
        return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
                mBitsPerSample, mChannelMode, mCodecSpecific1,
                mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
    }

    /**
     * Checks whether the object contains valid codec configuration.
     *
     * @return true if the object contains valid codec configuration, otherwise false.
     * @hide
     */
    public boolean isValid() {
        return (mSampleRate != SAMPLE_RATE_NONE)
                && (mBitsPerSample != BITS_PER_SAMPLE_NONE)
                && (mChannelMode != CHANNEL_MODE_NONE);
    }

    /**
     * Adds capability string to an existing string.
     *
     * @param prevStr the previous string with the capabilities. Can be a null pointer.
     * @param capStr the capability string to append to prevStr argument.
     * @return the result string in the form "prevStr|capStr".
     */
    private static String appendCapabilityToString(String prevStr,
            String capStr) {
        if (prevStr == null) {
            return capStr;
        }
        return prevStr + "|" + capStr;
    }

    @Override
    public String toString() {
        String sampleRateStr = null;
        if (mSampleRate == SAMPLE_RATE_NONE) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE");
        }
        if ((mSampleRate & SAMPLE_RATE_44100) != 0) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "44100");
        }
        if ((mSampleRate & SAMPLE_RATE_48000) != 0) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "48000");
        }
        if ((mSampleRate & SAMPLE_RATE_88200) != 0) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "88200");
        }
        if ((mSampleRate & SAMPLE_RATE_96000) != 0) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "96000");
        }
        if ((mSampleRate & SAMPLE_RATE_176400) != 0) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "176400");
        }
        if ((mSampleRate & SAMPLE_RATE_192000) != 0) {
            sampleRateStr = appendCapabilityToString(sampleRateStr, "192000");
        }

        String bitsPerSampleStr = null;
        if (mBitsPerSample == BITS_PER_SAMPLE_NONE) {
            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE");
        }
        if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) {
            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16");
        }
        if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) {
            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24");
        }
        if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) {
            bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32");
        }

        String channelModeStr = null;
        if (mChannelMode == CHANNEL_MODE_NONE) {
            channelModeStr = appendCapabilityToString(channelModeStr, "NONE");
        }
        if ((mChannelMode & CHANNEL_MODE_MONO) != 0) {
            channelModeStr = appendCapabilityToString(channelModeStr, "MONO");
        }
        if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
            channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
        }

        return "{codecName:" + getCodecName()
                + ",mCodecType:" + mCodecType
                + ",mCodecPriority:" + mCodecPriority
                + ",mSampleRate:" + String.format("0x%x", mSampleRate)
                + "(" + sampleRateStr + ")"
                + ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample)
                + "(" + bitsPerSampleStr + ")"
                + ",mChannelMode:" + String.format("0x%x", mChannelMode)
                + "(" + channelModeStr + ")"
                + ",mCodecSpecific1:" + mCodecSpecific1
                + ",mCodecSpecific2:" + mCodecSpecific2
                + ",mCodecSpecific3:" + mCodecSpecific3
                + ",mCodecSpecific4:" + mCodecSpecific4 + "}";
    }

    /**
     * Always returns 0
     *
     * @return 0
     * @hide
     */
    @Override
    public int describeContents() {
        return 0;
    }

    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothCodecConfig> CREATOR =
            new Parcelable.Creator<BluetoothCodecConfig>() {
                public BluetoothCodecConfig createFromParcel(Parcel in) {
                    final int codecType = in.readInt();
                    final int codecPriority = in.readInt();
                    final int sampleRate = in.readInt();
                    final int bitsPerSample = in.readInt();
                    final int channelMode = in.readInt();
                    final long codecSpecific1 = in.readLong();
                    final long codecSpecific2 = in.readLong();
                    final long codecSpecific3 = in.readLong();
                    final long codecSpecific4 = in.readLong();
                    return new BluetoothCodecConfig(codecType, codecPriority,
                            sampleRate, bitsPerSample,
                            channelMode, codecSpecific1,
                            codecSpecific2, codecSpecific3,
                            codecSpecific4);
                }

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

    /**
     * Flattens the object to a parcel
     *
     * @param out The Parcel in which the object should be written.
     * @param flags Additional flags about how the object should be written.
     *
     * @hide
     */
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mCodecType);
        out.writeInt(mCodecPriority);
        out.writeInt(mSampleRate);
        out.writeInt(mBitsPerSample);
        out.writeInt(mChannelMode);
        out.writeLong(mCodecSpecific1);
        out.writeLong(mCodecSpecific2);
        out.writeLong(mCodecSpecific3);
        out.writeLong(mCodecSpecific4);
    }

    /**
     * Gets the codec name.
     *
     * @return the codec name
     */
    public @NonNull String getCodecName() {
        switch (mCodecType) {
            case SOURCE_CODEC_TYPE_SBC:
                return "SBC";
            case SOURCE_CODEC_TYPE_AAC:
                return "AAC";
            case SOURCE_CODEC_TYPE_APTX:
                return "aptX";
            case SOURCE_CODEC_TYPE_APTX_HD:
                return "aptX HD";
            case SOURCE_CODEC_TYPE_LDAC:
                return "LDAC";
            case SOURCE_CODEC_TYPE_INVALID:
                return "INVALID CODEC";
            default:
                break;
        }
        return "UNKNOWN CODEC(" + mCodecType + ")";
    }

    /**
     * Gets the codec type.
     * See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}.
     *
     * @return the codec type
     */
    public @SourceCodecType int getCodecType() {
        return mCodecType;
    }

    /**
     * Checks whether the codec is mandatory.
     *
     * @return true if the codec is mandatory, otherwise false.
     */
    public boolean isMandatoryCodec() {
        return mCodecType == SOURCE_CODEC_TYPE_SBC;
    }

    /**
     * Gets the codec selection priority.
     * The codec selection priority is relative to other codecs: larger value
     * means higher priority. If 0, reset to default.
     *
     * @return the codec priority
     */
    public @CodecPriority int getCodecPriority() {
        return mCodecPriority;
    }

    /**
     * Sets the codec selection priority.
     * The codec selection priority is relative to other codecs: larger value
     * means higher priority. If 0, reset to default.
     *
     * @param codecPriority the codec priority
     * @hide
     */
    @UnsupportedAppUsage
    public void setCodecPriority(@CodecPriority int codecPriority) {
        mCodecPriority = codecPriority;
    }

    /**
     * Gets the codec sample rate. The value can be a bitmask with all
     * supported sample rates:
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_48000} or
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_88200} or
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_96000} or
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_176400} or
     * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_192000}
     *
     * @return the codec sample rate
     */
    public @SampleRate int getSampleRate() {
        return mSampleRate;
    }

    /**
     * Gets the codec bits per sample. The value can be a bitmask with all
     * bits per sample supported:
     * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or
     * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or
     * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_24} or
     * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_32}
     *
     * @return the codec bits per sample
     */
    public @BitsPerSample int getBitsPerSample() {
        return mBitsPerSample;
    }

    /**
     * Gets the codec channel mode. The value can be a bitmask with all
     * supported channel modes:
     * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
     * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
     * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO}
     *
     * @return the codec channel mode
     * @hide
     */
    @UnsupportedAppUsage
    public @ChannelMode int getChannelMode() {
        return mChannelMode;
    }

    /**
     * Gets a codec specific value1.
     *
     * @return a codec specific value1.
     */
    public long getCodecSpecific1() {
        return mCodecSpecific1;
    }

    /**
     * Gets a codec specific value2.
     *
     * @return a codec specific value2
     * @hide
     */
    @UnsupportedAppUsage
    public long getCodecSpecific2() {
        return mCodecSpecific2;
    }

    /**
     * Gets a codec specific value3.
     *
     * @return a codec specific value3
     * @hide
     */
    @UnsupportedAppUsage
    public long getCodecSpecific3() {
        return mCodecSpecific3;
    }

    /**
     * Gets a codec specific value4.
     *
     * @return a codec specific value4
     * @hide
     */
    @UnsupportedAppUsage
    public long getCodecSpecific4() {
        return mCodecSpecific4;
    }

    /**
     * Checks whether a value set presented by a bitmask has zero or single bit
     *
     * @param valueSet the value set presented by a bitmask
     * @return true if the valueSet contains zero or single bit, otherwise false.
     * @hide
     */
    private static boolean hasSingleBit(int valueSet) {
        return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0);
    }

    /**
     * Checks whether the object contains none or single sample rate.
     *
     * @return true if the object contains none or single sample rate, otherwise false.
     * @hide
     */
    public boolean hasSingleSampleRate() {
        return hasSingleBit(mSampleRate);
    }

    /**
     * Checks whether the object contains none or single bits per sample.
     *
     * @return true if the object contains none or single bits per sample, otherwise false.
     * @hide
     */
    public boolean hasSingleBitsPerSample() {
        return hasSingleBit(mBitsPerSample);
    }

    /**
     * Checks whether the object contains none or single channel mode.
     *
     * @return true if the object contains none or single channel mode, otherwise false.
     * @hide
     */
    public boolean hasSingleChannelMode() {
        return hasSingleBit(mChannelMode);
    }

    /**
     * Checks whether the audio feeding parameters are same.
     *
     * @param other the codec config to compare against
     * @return true if the audio feeding parameters are same, otherwise false
     * @hide
     */
    public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
        return (other != null && other.mSampleRate == mSampleRate
                && other.mBitsPerSample == mBitsPerSample
                && other.mChannelMode == mChannelMode);
    }

    /**
     * Checks whether another codec config has the similar feeding parameters.
     * Any parameters with NONE value will be considered to be a wildcard matching.
     *
     * @param other the codec config to compare against
     * @return true if the audio feeding parameters are similar, otherwise false.
     * @hide
     */
    public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) {
        if (other == null || mCodecType != other.mCodecType) {
            return false;
        }
        int sampleRate = other.mSampleRate;
        if (mSampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE
                || sampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE) {
            sampleRate = mSampleRate;
        }
        int bitsPerSample = other.mBitsPerSample;
        if (mBitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE
                || bitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) {
            bitsPerSample = mBitsPerSample;
        }
        int channelMode = other.mChannelMode;
        if (mChannelMode == BluetoothCodecConfig.CHANNEL_MODE_NONE
                || channelMode == BluetoothCodecConfig.CHANNEL_MODE_NONE) {
            channelMode = mChannelMode;
        }
        return sameAudioFeedingParameters(new BluetoothCodecConfig(
                mCodecType, /* priority */ 0, sampleRate, bitsPerSample, channelMode,
                /* specific1 */ 0, /* specific2 */ 0, /* specific3 */ 0,
                /* specific4 */ 0));
    }

    /**
     * Checks whether the codec specific parameters are the same.
     *
     * @param other the codec config to compare against
     * @return true if the codec specific parameters are the same, otherwise false.
     * @hide
     */
    public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) {
        if (other == null && mCodecType != other.mCodecType) {
            return false;
        }
        // Currently we only care about the LDAC Playback Quality at CodecSpecific1
        switch (mCodecType) {
            case SOURCE_CODEC_TYPE_LDAC:
                if (mCodecSpecific1 != other.mCodecSpecific1) {
                    return false;
                }
                // fall through
            default:
                return true;
        }
    }
}
