/*
 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc.audio;

import static android.media.AudioManager.MODE_IN_CALL;
import static android.media.AudioManager.MODE_IN_COMMUNICATION;
import static android.media.AudioManager.MODE_NORMAL;
import static android.media.AudioManager.MODE_RINGTONE;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.MediaRecorder.AudioSource;
import android.os.Build;
import java.lang.Thread;
import java.util.Arrays;
import org.webrtc.Logging;

final class WebRtcAudioUtils {
  private static final String TAG = "WebRtcAudioUtilsExternal";

  // Helper method for building a string of thread information.
  public static String getThreadInfo() {
    return "@[name=" + Thread.currentThread().getName() + ", id=" + Thread.currentThread().getId()
        + "]";
  }

  // Returns true if we're running on emulator.
  public static boolean runningOnEmulator() {
    return Build.HARDWARE.equals("goldfish") && Build.BRAND.startsWith("generic_");
  }

  // Information about the current build, taken from system properties.
  static void logDeviceInfo(String tag) {
    Logging.d(tag,
        "Android SDK: " + Build.VERSION.SDK_INT + ", "
            + "Release: " + Build.VERSION.RELEASE + ", "
            + "Brand: " + Build.BRAND + ", "
            + "Device: " + Build.DEVICE + ", "
            + "Id: " + Build.ID + ", "
            + "Hardware: " + Build.HARDWARE + ", "
            + "Manufacturer: " + Build.MANUFACTURER + ", "
            + "Model: " + Build.MODEL + ", "
            + "Product: " + Build.PRODUCT);
  }

  // Logs information about the current audio state. The idea is to call this
  // method when errors are detected to log under what conditions the error
  // occurred. Hopefully it will provide clues to what might be the root cause.
  static void logAudioState(String tag, Context context, AudioManager audioManager) {
    logDeviceInfo(tag);
    logAudioStateBasic(tag, context, audioManager);
    logAudioStateVolume(tag, audioManager);
    logAudioDeviceInfo(tag, audioManager);
  }

  // Converts AudioDeviceInfo types to local string representation.
  static String deviceTypeToString(int type) {
    switch (type) {
      case AudioDeviceInfo.TYPE_UNKNOWN:
        return "TYPE_UNKNOWN";
      case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
        return "TYPE_BUILTIN_EARPIECE";
      case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
        return "TYPE_BUILTIN_SPEAKER";
      case AudioDeviceInfo.TYPE_WIRED_HEADSET:
        return "TYPE_WIRED_HEADSET";
      case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
        return "TYPE_WIRED_HEADPHONES";
      case AudioDeviceInfo.TYPE_LINE_ANALOG:
        return "TYPE_LINE_ANALOG";
      case AudioDeviceInfo.TYPE_LINE_DIGITAL:
        return "TYPE_LINE_DIGITAL";
      case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
        return "TYPE_BLUETOOTH_SCO";
      case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
        return "TYPE_BLUETOOTH_A2DP";
      case AudioDeviceInfo.TYPE_HDMI:
        return "TYPE_HDMI";
      case AudioDeviceInfo.TYPE_HDMI_ARC:
        return "TYPE_HDMI_ARC";
      case AudioDeviceInfo.TYPE_USB_DEVICE:
        return "TYPE_USB_DEVICE";
      case AudioDeviceInfo.TYPE_USB_ACCESSORY:
        return "TYPE_USB_ACCESSORY";
      case AudioDeviceInfo.TYPE_DOCK:
        return "TYPE_DOCK";
      case AudioDeviceInfo.TYPE_FM:
        return "TYPE_FM";
      case AudioDeviceInfo.TYPE_BUILTIN_MIC:
        return "TYPE_BUILTIN_MIC";
      case AudioDeviceInfo.TYPE_FM_TUNER:
        return "TYPE_FM_TUNER";
      case AudioDeviceInfo.TYPE_TV_TUNER:
        return "TYPE_TV_TUNER";
      case AudioDeviceInfo.TYPE_TELEPHONY:
        return "TYPE_TELEPHONY";
      case AudioDeviceInfo.TYPE_AUX_LINE:
        return "TYPE_AUX_LINE";
      case AudioDeviceInfo.TYPE_IP:
        return "TYPE_IP";
      case AudioDeviceInfo.TYPE_BUS:
        return "TYPE_BUS";
      case AudioDeviceInfo.TYPE_USB_HEADSET:
        return "TYPE_USB_HEADSET";
      default:
        return "TYPE_UNKNOWN";
    }
  }

  @TargetApi(Build.VERSION_CODES.N)
  public static String audioSourceToString(int source) {
    // AudioSource.UNPROCESSED requires API level 29. Use local define instead.
    final int VOICE_PERFORMANCE = 10;
    switch (source) {
      case AudioSource.DEFAULT:
        return "DEFAULT";
      case AudioSource.MIC:
        return "MIC";
      case AudioSource.VOICE_UPLINK:
        return "VOICE_UPLINK";
      case AudioSource.VOICE_DOWNLINK:
        return "VOICE_DOWNLINK";
      case AudioSource.VOICE_CALL:
        return "VOICE_CALL";
      case AudioSource.CAMCORDER:
        return "CAMCORDER";
      case AudioSource.VOICE_RECOGNITION:
        return "VOICE_RECOGNITION";
      case AudioSource.VOICE_COMMUNICATION:
        return "VOICE_COMMUNICATION";
      case AudioSource.UNPROCESSED:
        return "UNPROCESSED";
      case VOICE_PERFORMANCE:
        return "VOICE_PERFORMANCE";
      default:
        return "INVALID";
    }
  }

  public static String channelMaskToString(int mask) {
    // For input or AudioRecord, the mask should be AudioFormat#CHANNEL_IN_MONO or
    // AudioFormat#CHANNEL_IN_STEREO. AudioFormat#CHANNEL_IN_MONO is guaranteed to work on all
    // devices.
    switch (mask) {
      case AudioFormat.CHANNEL_IN_STEREO:
        return "IN_STEREO";
      case AudioFormat.CHANNEL_IN_MONO:
        return "IN_MONO";
      default:
        return "INVALID";
    }
  }

  @TargetApi(Build.VERSION_CODES.N)
  public static String audioEncodingToString(int enc) {
    switch (enc) {
      case AudioFormat.ENCODING_INVALID:
        return "INVALID";
      case AudioFormat.ENCODING_PCM_16BIT:
        return "PCM_16BIT";
      case AudioFormat.ENCODING_PCM_8BIT:
        return "PCM_8BIT";
      case AudioFormat.ENCODING_PCM_FLOAT:
        return "PCM_FLOAT";
      case AudioFormat.ENCODING_AC3:
        return "AC3";
      case AudioFormat.ENCODING_E_AC3:
        return "AC3";
      case AudioFormat.ENCODING_DTS:
        return "DTS";
      case AudioFormat.ENCODING_DTS_HD:
        return "DTS_HD";
      case AudioFormat.ENCODING_MP3:
        return "MP3";
      default:
        return "Invalid encoding: " + enc;
    }
  }

  // Reports basic audio statistics.
  private static void logAudioStateBasic(String tag, Context context, AudioManager audioManager) {
    Logging.d(tag,
        "Audio State: "
            + "audio mode: " + modeToString(audioManager.getMode()) + ", "
            + "has mic: " + hasMicrophone(context) + ", "
            + "mic muted: " + audioManager.isMicrophoneMute() + ", "
            + "music active: " + audioManager.isMusicActive() + ", "
            + "speakerphone: " + audioManager.isSpeakerphoneOn() + ", "
            + "BT SCO: " + audioManager.isBluetoothScoOn());
  }

  private static boolean isVolumeFixed(AudioManager audioManager) {
    if (Build.VERSION.SDK_INT < 21) {
      return false;
    }
    return audioManager.isVolumeFixed();
  }

  // Adds volume information for all possible stream types.
  private static void logAudioStateVolume(String tag, AudioManager audioManager) {
    final int[] streams = {AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_MUSIC,
        AudioManager.STREAM_RING, AudioManager.STREAM_ALARM, AudioManager.STREAM_NOTIFICATION,
        AudioManager.STREAM_SYSTEM};
    Logging.d(tag, "Audio State: ");
    // Some devices may not have volume controls and might use a fixed volume.
    boolean fixedVolume = isVolumeFixed(audioManager);
    Logging.d(tag, "  fixed volume=" + fixedVolume);
    if (!fixedVolume) {
      for (int stream : streams) {
        StringBuilder info = new StringBuilder();
        info.append("  " + streamTypeToString(stream) + ": ");
        info.append("volume=").append(audioManager.getStreamVolume(stream));
        info.append(", max=").append(audioManager.getStreamMaxVolume(stream));
        logIsStreamMute(tag, audioManager, stream, info);
        Logging.d(tag, info.toString());
      }
    }
  }

  private static void logIsStreamMute(
      String tag, AudioManager audioManager, int stream, StringBuilder info) {
    if (Build.VERSION.SDK_INT >= 23) {
      info.append(", muted=").append(audioManager.isStreamMute(stream));
    }
  }

  private static void logAudioDeviceInfo(String tag, AudioManager audioManager) {
    if (Build.VERSION.SDK_INT < 23) {
      return;
    }
    final AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
    if (devices.length == 0) {
      return;
    }
    Logging.d(tag, "Audio Devices: ");
    for (AudioDeviceInfo device : devices) {
      StringBuilder info = new StringBuilder();
      info.append("  ").append(deviceTypeToString(device.getType()));
      info.append(device.isSource() ? "(in): " : "(out): ");
      // An empty array indicates that the device supports arbitrary channel counts.
      if (device.getChannelCounts().length > 0) {
        info.append("channels=").append(Arrays.toString(device.getChannelCounts()));
        info.append(", ");
      }
      if (device.getEncodings().length > 0) {
        // Examples: ENCODING_PCM_16BIT = 2, ENCODING_PCM_FLOAT = 4.
        info.append("encodings=").append(Arrays.toString(device.getEncodings()));
        info.append(", ");
      }
      if (device.getSampleRates().length > 0) {
        info.append("sample rates=").append(Arrays.toString(device.getSampleRates()));
        info.append(", ");
      }
      info.append("id=").append(device.getId());
      Logging.d(tag, info.toString());
    }
  }

  // Converts media.AudioManager modes into local string representation.
  static String modeToString(int mode) {
    switch (mode) {
      case MODE_IN_CALL:
        return "MODE_IN_CALL";
      case MODE_IN_COMMUNICATION:
        return "MODE_IN_COMMUNICATION";
      case MODE_NORMAL:
        return "MODE_NORMAL";
      case MODE_RINGTONE:
        return "MODE_RINGTONE";
      default:
        return "MODE_INVALID";
    }
  }

  private static String streamTypeToString(int stream) {
    switch (stream) {
      case AudioManager.STREAM_VOICE_CALL:
        return "STREAM_VOICE_CALL";
      case AudioManager.STREAM_MUSIC:
        return "STREAM_MUSIC";
      case AudioManager.STREAM_RING:
        return "STREAM_RING";
      case AudioManager.STREAM_ALARM:
        return "STREAM_ALARM";
      case AudioManager.STREAM_NOTIFICATION:
        return "STREAM_NOTIFICATION";
      case AudioManager.STREAM_SYSTEM:
        return "STREAM_SYSTEM";
      default:
        return "STREAM_INVALID";
    }
  }

  // Returns true if the device can record audio via a microphone.
  private static boolean hasMicrophone(Context context) {
    return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
  }
}
