/*
 * Copyright (C) 2015 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 com.android.contacts.common.compat;

import android.net.Uri;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccountHandle;
import android.telephony.TelephonyManager;

import com.android.contacts.common.ContactsUtils;

public class TelephonyManagerCompat {
    public static final String TELEPHONY_MANAGER_CLASS = "android.telephony.TelephonyManager";

    /**
     * @param telephonyManager The telephony manager instance to use for method calls.
     * @return true if the current device is "voice capable".
     * <p>
     * "Voice capable" means that this device supports circuit-switched
     * (i.e. voice) phone calls over the telephony network, and is allowed
     * to display the in-call UI while a cellular voice call is active.
     * This will be false on "data only" devices which can't make voice
     * calls and don't support any in-call UI.
     * <p>
     * Note: the meaning of this flag is subtly different from the
     * PackageManager.FEATURE_TELEPHONY system feature, which is available
     * on any device with a telephony radio, even if the device is
     * data-only.
     */
    public static boolean isVoiceCapable(@Nullable TelephonyManager telephonyManager) {
        if (telephonyManager == null) {
            return false;
        }
        if (CompatUtils.isLollipopMr1Compatible()
                || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS, "isVoiceCapable")) {
            // isVoiceCapable was unhidden in L-MR1
            return telephonyManager.isVoiceCapable();
        }
        final int phoneType = telephonyManager.getPhoneType();
        return phoneType == TelephonyManager.PHONE_TYPE_CDMA ||
                phoneType == TelephonyManager.PHONE_TYPE_GSM;
    }

    /**
     * Returns the number of phones available.
     * Returns 1 for Single standby mode (Single SIM functionality)
     * Returns 2 for Dual standby mode.(Dual SIM functionality)
     *
     * Returns 1 if the method or telephonyManager is not available.
     *
     * @param telephonyManager The telephony manager instance to use for method calls.
     */
    public static int getPhoneCount(@Nullable TelephonyManager telephonyManager) {
        if (telephonyManager == null) {
            return 1;
        }
        if (CompatUtils.isMarshmallowCompatible() || CompatUtils
                .isMethodAvailable(TELEPHONY_MANAGER_CLASS, "getPhoneCount")) {
            return telephonyManager.getPhoneCount();
        }
        return 1;
    }

    /**
     * Returns the unique device ID of a subscription, for example, the IMEI for
     * GSM and the MEID for CDMA phones. Return null if device ID is not available.
     *
     * <p>Requires Permission:
     *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
     *
     * @param telephonyManager The telephony manager instance to use for method calls.
     * @param slotId of which deviceID is returned
     */
    public static String getDeviceId(@Nullable TelephonyManager telephonyManager, int slotId) {
        if (telephonyManager == null) {
            return null;
        }
        if (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS,
                        "getDeviceId", Integer.class)) {
            return telephonyManager.getDeviceId(slotId);
        }
        return null;
    }

    /**
     * Whether the phone supports TTY mode.
     *
     * @param telephonyManager The telephony manager instance to use for method calls.
     * @return {@code true} if the device supports TTY mode, and {@code false} otherwise.
     */

    public static boolean isTtyModeSupported(@Nullable TelephonyManager telephonyManager) {
        if (telephonyManager == null) {
            return false;
        }
        if (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS, "isTtyModeSupported")) {
            return telephonyManager.isTtyModeSupported();
        }
        return false;
    }

    /**
     * Whether the phone supports hearing aid compatibility.
     *
     * @param telephonyManager The telephony manager instance to use for method calls.
     * @return {@code true} if the device supports hearing aid compatibility, and {@code false}
     * otherwise.
     */
    public static boolean isHearingAidCompatibilitySupported(
            @Nullable TelephonyManager telephonyManager) {
        if (telephonyManager == null) {
            return false;
        }
        if (CompatUtils.isMarshmallowCompatible()
                || CompatUtils.isMethodAvailable(TELEPHONY_MANAGER_CLASS,
                        "isHearingAidCompatibilitySupported")) {
            return telephonyManager.isHearingAidCompatibilitySupported();
        }
        return false;
    }

    /**
     * Returns the URI for the per-account voicemail ringtone set in Phone settings.
     *
     * @param telephonyManager The telephony manager instance to use for method calls.
     * @param accountHandle The handle for the {@link android.telecom.PhoneAccount} for which to
     * retrieve the voicemail ringtone.
     * @return The URI for the ringtone to play when receiving a voicemail from a specific
     * PhoneAccount.
     */
    @Nullable
    public static Uri getVoicemailRingtoneUri(TelephonyManager telephonyManager,
            PhoneAccountHandle accountHandle) {
        if (!CompatUtils.isNCompatible()) {
            return null;
        }
        return TelephonyManagerSdkCompat
                .getVoicemailRingtoneUri(telephonyManager, accountHandle);
    }

    /**
     * Returns whether vibration is set for voicemail notification in Phone settings.
     *
     * @param telephonyManager The telephony manager instance to use for method calls.
     * @param accountHandle The handle for the {@link android.telecom.PhoneAccount} for which to
     * retrieve the voicemail vibration setting.
     * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
     */
    public static boolean isVoicemailVibrationEnabled(TelephonyManager telephonyManager,
            PhoneAccountHandle accountHandle) {
        if (!CompatUtils.isNCompatible()) {
            return true;
        }
        return TelephonyManagerSdkCompat
                .isVoicemailVibrationEnabled(telephonyManager, accountHandle);
    }
}
