package com.android.incallui;

import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.IBinder;
import android.telecom.VideoProfile;

import com.android.dialer.common.LogUtil;
import com.android.incallui.call.DialerCall;

import java.lang.reflect.Method;

public final class SecureLineCallUnlockProtection {
  private static final String TAG = "SecureLineCallUnlockProtection";

  private SecureLineCallUnlockProtection() {}

  public static void answerOrRequestUnlock(
      Activity activity,
      DialerCall call,
      int videoState) {

    if (activity == null || call == null) {
      return;
    }

    if (!shouldRequireUnlock(activity)) {
      call.answer(videoState);
      return;
    }

    KeyguardManager km = activity.getSystemService(KeyguardManager.class);

    if (km == null || !km.isDeviceLocked()) {
      call.answer(videoState);
      return;
    }

    LogUtil.i(TAG + ".answerOrRequestUnlock", "Requesting unlock before answering call");

    km.requestDismissKeyguard(
        activity,
        new KeyguardManager.KeyguardDismissCallback() {
          @Override
          public void onDismissSucceeded() {
            LogUtil.i(TAG + ".onDismissSucceeded", "Unlocked. Answering call.");
            call.answer(videoState);
          }

          @Override
          public void onDismissCancelled() {
            LogUtil.i(TAG + ".onDismissCancelled", "Unlock cancelled. Call not answered.");
          }

          @Override
          public void onDismissError() {
            LogUtil.e(TAG + ".onDismissError", "Unlock failed. Call not answered.");
          }
        });
  }

  public static void answerOrRequestUnlock(
      Activity activity,
      DialerCall call) {
    answerOrRequestUnlock(activity, call, VideoProfile.STATE_AUDIO_ONLY);
  }

  public static boolean shouldRequireUnlock(Context context) {
    try {
      Object sl = getSecureLineService();

      if (sl == null) {
        LogUtil.w(TAG + ".shouldRequireUnlock", "SecureLine service unavailable");
        return false;
      }

      Method isEnabled = sl.getClass().getMethod("isCallUnlockProtectionEnabled");
      return Boolean.TRUE.equals(isEnabled.invoke(sl));
    } catch (Throwable t) {
      LogUtil.e(TAG + ".shouldRequireUnlock", "Unexpected failure", t);
      return false;
    }
  }

  private static Object getSecureLineService() throws Exception {
    Method getService =
        Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
    IBinder binder = (IBinder) getService.invoke(null, "secureline");

    if (binder == null) {
      return null;
    }

    Class<?> stub = Class.forName("com.android.secureline.ISecureLineManager$Stub");
    Method asInterface = stub.getMethod("asInterface", IBinder.class);
    return asInterface.invoke(null, binder);
  }
}
