/*
 * 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 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);
    }
}
