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

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *  Encapsulates the telecom audio state, including the current audio routing, supported audio
 *  routing and mute.
 */
public final class CallAudioState implements Parcelable {
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value={ROUTE_EARPIECE, ROUTE_BLUETOOTH, ROUTE_WIRED_HEADSET, ROUTE_SPEAKER},
            flag=true)
    public @interface CallAudioRoute {}

    /** Direct the audio stream through the device's earpiece. */
    public static final int ROUTE_EARPIECE      = 0x00000001;

    /** Direct the audio stream through Bluetooth. */
    public static final int ROUTE_BLUETOOTH     = 0x00000002;

    /** Direct the audio stream through a wired headset. */
    public static final int ROUTE_WIRED_HEADSET = 0x00000004;

    /** Direct the audio stream through the device's speakerphone. */
    public static final int ROUTE_SPEAKER       = 0x00000008;

    /**
     * Direct the audio stream through the device's earpiece or wired headset if one is
     * connected.
     */
    public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET;

    /**
     * Bit mask of all possible audio routes.
     *
     * @hide
     **/
    public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
            ROUTE_SPEAKER;

    private final boolean isMuted;
    private final int route;
    private final int supportedRouteMask;
    private final BluetoothDevice activeBluetoothDevice;
    private final Collection<BluetoothDevice> supportedBluetoothDevices;

    /**
     * Constructor for a {@link CallAudioState} object.
     *
     * @param muted {@code true} if the call is muted, {@code false} otherwise.
     * @param route The current audio route being used.
     * Allowed values:
     * {@link #ROUTE_EARPIECE}
     * {@link #ROUTE_BLUETOOTH}
     * {@link #ROUTE_WIRED_HEADSET}
     * {@link #ROUTE_SPEAKER}
     * @param supportedRouteMask Bit mask of all routes supported by this call. This should be a
     * bitwise combination of the following values:
     * {@link #ROUTE_EARPIECE}
     * {@link #ROUTE_BLUETOOTH}
     * {@link #ROUTE_WIRED_HEADSET}
     * {@link #ROUTE_SPEAKER}
     */
    public CallAudioState(boolean muted, @CallAudioRoute int route,
            @CallAudioRoute int supportedRouteMask) {
        this(muted, route, supportedRouteMask, null, Collections.emptyList());
    }

    /** @hide */
    @TestApi
    public CallAudioState(boolean isMuted, @CallAudioRoute int route,
            @CallAudioRoute int supportedRouteMask,
            @Nullable BluetoothDevice activeBluetoothDevice,
            @NonNull Collection<BluetoothDevice> supportedBluetoothDevices) {
        this.isMuted = isMuted;
        this.route = route;
        this.supportedRouteMask = supportedRouteMask;
        this.activeBluetoothDevice = activeBluetoothDevice;
        this.supportedBluetoothDevices = supportedBluetoothDevices;
    }

    /** @hide */
    public CallAudioState(CallAudioState state) {
        isMuted = state.isMuted();
        route = state.getRoute();
        supportedRouteMask = state.getSupportedRouteMask();
        activeBluetoothDevice = state.activeBluetoothDevice;
        supportedBluetoothDevices = state.getSupportedBluetoothDevices();
    }

    /** @hide */
    @SuppressWarnings("deprecation")
    public CallAudioState(AudioState state) {
        isMuted = state.isMuted();
        route = state.getRoute();
        supportedRouteMask = state.getSupportedRouteMask();
        activeBluetoothDevice = null;
        supportedBluetoothDevices = Collections.emptyList();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof CallAudioState)) {
            return false;
        }
        CallAudioState state = (CallAudioState) obj;
        if (supportedBluetoothDevices.size() != state.supportedBluetoothDevices.size()) {
            return false;
        }
        for (BluetoothDevice device : supportedBluetoothDevices) {
            if (!state.supportedBluetoothDevices.contains(device)) {
                return false;
            }
        }
        return Objects.equals(activeBluetoothDevice, state.activeBluetoothDevice) && isMuted() ==
                state.isMuted() && getRoute() == state.getRoute() && getSupportedRouteMask() ==
                state.getSupportedRouteMask();
    }

    @Override
    public String toString() {
        String bluetoothDeviceList = supportedBluetoothDevices.stream()
                .map(BluetoothDevice::getAddress).collect(Collectors.joining(", "));

        return String.format(Locale.US,
                "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s, " +
                        "activeBluetoothDevice: [%s], supportedBluetoothDevices: [%s]]",
                isMuted,
                audioRouteToString(route),
                audioRouteToString(supportedRouteMask),
                activeBluetoothDevice,
                bluetoothDeviceList);
    }

    /**
     * @return {@code true} if the call is muted, {@code false} otherwise.
     */
    public boolean isMuted() {
        return isMuted;
    }

    /**
     * @return The current audio route being used.
     */
    @CallAudioRoute
    public int getRoute() {
        return route;
    }

    /**
     * @return Bit mask of all routes supported by this call.
     */
    @CallAudioRoute
    public int getSupportedRouteMask() {
        return supportedRouteMask;
    }

    /**
     * @return The {@link BluetoothDevice} through which audio is being routed.
     *         Will not be {@code null} if {@link #getRoute()} returns {@link #ROUTE_BLUETOOTH}.
     */
    public BluetoothDevice getActiveBluetoothDevice() {
        return activeBluetoothDevice;
    }

    /**
     * @return {@link List} of {@link BluetoothDevice}s that can be used for this call.
     */
    public Collection<BluetoothDevice> getSupportedBluetoothDevices() {
        return supportedBluetoothDevices;
    }

    /**
     * Converts the provided audio route into a human readable string representation.
     *
     * @param route to convert into a string.
     *
     * @return String representation of the provided audio route.
     */
    public static String audioRouteToString(int route) {
        if (route == 0 || (route & ~ROUTE_ALL) != 0x0) {
            return "UNKNOWN";
        }

        StringBuffer buffer = new StringBuffer();
        if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) {
            listAppend(buffer, "EARPIECE");
        }
        if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) {
            listAppend(buffer, "BLUETOOTH");
        }
        if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) {
            listAppend(buffer, "WIRED_HEADSET");
        }
        if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) {
            listAppend(buffer, "SPEAKER");
        }

        return buffer.toString();
    }

    /**
     * Responsible for creating AudioState objects for deserialized Parcels.
     */
    public static final @android.annotation.NonNull Parcelable.Creator<CallAudioState> CREATOR =
            new Parcelable.Creator<CallAudioState> () {

        @Override
        public CallAudioState createFromParcel(Parcel source) {
            boolean isMuted = source.readByte() == 0 ? false : true;
            int route = source.readInt();
            int supportedRouteMask = source.readInt();
            BluetoothDevice activeBluetoothDevice = source.readParcelable(
                    ClassLoader.getSystemClassLoader());
            List<BluetoothDevice> supportedBluetoothDevices = new ArrayList<>();
            source.readParcelableList(supportedBluetoothDevices,
                    ClassLoader.getSystemClassLoader());
            return new CallAudioState(isMuted, route,
                    supportedRouteMask, activeBluetoothDevice, supportedBluetoothDevices);
        }

        @Override
        public CallAudioState[] newArray(int size) {
            return new CallAudioState[size];
        }
    };

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

    /**
     * Writes AudioState object into a serializeable Parcel.
     */
    @Override
    public void writeToParcel(Parcel destination, int flags) {
        destination.writeByte((byte) (isMuted ? 1 : 0));
        destination.writeInt(route);
        destination.writeInt(supportedRouteMask);
        destination.writeParcelable(activeBluetoothDevice, 0);
        destination.writeParcelableList(new ArrayList<>(supportedBluetoothDevices), 0);
    }

    private static void listAppend(StringBuffer buffer, String str) {
        if (buffer.length() > 0) {
            buffer.append(", ");
        }
        buffer.append(str);
    }
}
