package io.flutter.plugin.text;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import androidx.annotation.RequiresApi;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.systemchannels.ProcessTextChannel;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.StandardMethodCodec;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

@RunWith(AndroidJUnit4.class)
@TargetApi(Build.VERSION_CODES.N)
@RequiresApi(Build.VERSION_CODES.N)
public class ProcessTextPluginTest {

  private static void sendToBinaryMessageHandler(
      BinaryMessenger.BinaryMessageHandler binaryMessageHandler, String method, Object args) {
    MethodCall methodCall = new MethodCall(method, args);
    ByteBuffer encodedMethodCall = StandardMethodCodec.INSTANCE.encodeMethodCall(methodCall);
    binaryMessageHandler.onMessage(
        (ByteBuffer) encodedMethodCall.flip(), mock(BinaryMessenger.BinaryReply.class));
  }

  @SuppressWarnings("deprecation")
  // setMessageHandler is deprecated.
  @Test
  public void respondsToProcessTextChannelMessage() {
    ArgumentCaptor<BinaryMessenger.BinaryMessageHandler> binaryMessageHandlerCaptor =
        ArgumentCaptor.forClass(BinaryMessenger.BinaryMessageHandler.class);
    DartExecutor mockBinaryMessenger = mock(DartExecutor.class);
    ProcessTextChannel.ProcessTextMethodHandler mockHandler =
        mock(ProcessTextChannel.ProcessTextMethodHandler.class);
    PackageManager mockPackageManager = mock(PackageManager.class);
    ProcessTextChannel processTextChannel =
        new ProcessTextChannel(mockBinaryMessenger, mockPackageManager);

    processTextChannel.setMethodHandler(mockHandler);

    verify(mockBinaryMessenger, times(1))
        .setMessageHandler(any(String.class), binaryMessageHandlerCaptor.capture());

    BinaryMessenger.BinaryMessageHandler binaryMessageHandler =
        binaryMessageHandlerCaptor.getValue();

    sendToBinaryMessageHandler(binaryMessageHandler, "ProcessText.queryTextActions", null);

    verify(mockHandler).queryTextActions();
  }

  @SuppressWarnings("deprecation")
  // setMessageHandler is deprecated.
  @Test
  public void performQueryTextActions() {
    DartExecutor mockBinaryMessenger = mock(DartExecutor.class);
    PackageManager mockPackageManager = mock(PackageManager.class);
    ProcessTextChannel processTextChannel =
        new ProcessTextChannel(mockBinaryMessenger, mockPackageManager);

    // Set up mocked result for PackageManager.queryIntentActivities.
    ResolveInfo action1 = createFakeResolveInfo("Action1", mockPackageManager);
    ResolveInfo action2 = createFakeResolveInfo("Action2", mockPackageManager);
    List<ResolveInfo> infos = new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
    Intent intent = new Intent().setAction(Intent.ACTION_PROCESS_TEXT).setType("text/plain");
    when(mockPackageManager.queryIntentActivities(
            any(Intent.class), any(PackageManager.ResolveInfoFlags.class)))
        .thenReturn(infos);

    // ProcessTextPlugin should retrieve the mocked text actions.
    ProcessTextPlugin processTextPlugin = new ProcessTextPlugin(processTextChannel);
    Map<String, String> textActions = processTextPlugin.queryTextActions();
    final String action1Id = "mockActivityName.Action1";
    final String action2Id = "mockActivityName.Action2";
    assertEquals(textActions, Map.of(action1Id, "Action1", action2Id, "Action2"));
  }

  @SuppressWarnings("deprecation")
  // setMessageHandler is deprecated.
  @Test
  public void performProcessTextActionWithNoReturnedValue() {
    DartExecutor mockBinaryMessenger = mock(DartExecutor.class);
    PackageManager mockPackageManager = mock(PackageManager.class);
    ProcessTextChannel processTextChannel =
        new ProcessTextChannel(mockBinaryMessenger, mockPackageManager);

    // Set up mocked result for PackageManager.queryIntentActivities.
    ResolveInfo action1 = createFakeResolveInfo("Action1", mockPackageManager);
    ResolveInfo action2 = createFakeResolveInfo("Action2", mockPackageManager);
    List<ResolveInfo> infos = new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
    when(mockPackageManager.queryIntentActivities(
            any(Intent.class), any(PackageManager.ResolveInfoFlags.class)))
        .thenReturn(infos);

    // ProcessTextPlugin should retrieve the mocked text actions.
    ProcessTextPlugin processTextPlugin = new ProcessTextPlugin(processTextChannel);
    Map<String, String> textActions = processTextPlugin.queryTextActions();
    final String action1Id = "mockActivityName.Action1";
    final String action2Id = "mockActivityName.Action2";
    assertEquals(textActions, Map.of(action1Id, "Action1", action2Id, "Action2"));

    // Set up the activity binding.
    ActivityPluginBinding mockActivityPluginBinding = mock(ActivityPluginBinding.class);
    Activity mockActivity = mock(Activity.class);
    when(mockActivityPluginBinding.getActivity()).thenReturn(mockActivity);
    processTextPlugin.onAttachedToActivity(mockActivityPluginBinding);

    // Execute th first action.
    String textToBeProcessed = "Flutter!";
    MethodChannel.Result result = mock(MethodChannel.Result.class);
    processTextPlugin.processTextAction(action1Id, textToBeProcessed, false, result);

    // Activity.startActivityForResult should have been called.
    ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
    verify(mockActivity, times(1)).startActivityForResult(intentCaptor.capture(), anyInt());
    Intent intent = intentCaptor.getValue();
    assertEquals(intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT), textToBeProcessed);

    // Simulate an Android activity answer which does not return a value.
    Intent resultIntent = new Intent();
    processTextPlugin.onActivityResult(result.hashCode(), Activity.RESULT_OK, resultIntent);

    // Success with no returned value is expected.
    verify(result).success(null);
  }

  @SuppressWarnings("deprecation")
  // setMessageHandler is deprecated.
  @Test
  public void performProcessTextActionWithReturnedValue() {
    DartExecutor mockBinaryMessenger = mock(DartExecutor.class);
    PackageManager mockPackageManager = mock(PackageManager.class);
    ProcessTextChannel processTextChannel =
        new ProcessTextChannel(mockBinaryMessenger, mockPackageManager);

    // Set up mocked result for PackageManager.queryIntentActivities.
    ResolveInfo action1 = createFakeResolveInfo("Action1", mockPackageManager);
    ResolveInfo action2 = createFakeResolveInfo("Action2", mockPackageManager);
    List<ResolveInfo> infos = new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
    when(mockPackageManager.queryIntentActivities(
            any(Intent.class), any(PackageManager.ResolveInfoFlags.class)))
        .thenReturn(infos);

    // ProcessTextPlugin should retrieve the mocked text actions.
    ProcessTextPlugin processTextPlugin = new ProcessTextPlugin(processTextChannel);
    Map<String, String> textActions = processTextPlugin.queryTextActions();
    final String action1Id = "mockActivityName.Action1";
    final String action2Id = "mockActivityName.Action2";
    assertEquals(textActions, Map.of(action1Id, "Action1", action2Id, "Action2"));

    // Set up the activity binding.
    ActivityPluginBinding mockActivityPluginBinding = mock(ActivityPluginBinding.class);
    Activity mockActivity = mock(Activity.class);
    when(mockActivityPluginBinding.getActivity()).thenReturn(mockActivity);
    processTextPlugin.onAttachedToActivity(mockActivityPluginBinding);

    // Execute the first action.
    String textToBeProcessed = "Flutter!";
    MethodChannel.Result result = mock(MethodChannel.Result.class);
    processTextPlugin.processTextAction(action1Id, textToBeProcessed, false, result);

    // Activity.startActivityForResult should have been called.
    ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
    verify(mockActivity, times(1)).startActivityForResult(intentCaptor.capture(), anyInt());
    Intent intent = intentCaptor.getValue();
    assertEquals(intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT), textToBeProcessed);

    // Simulate an Android activity answer which returns a transformed text.
    String processedText = "Flutter!!!";
    Intent resultIntent = new Intent();
    resultIntent.putExtra(Intent.EXTRA_PROCESS_TEXT, processedText);
    processTextPlugin.onActivityResult(result.hashCode(), Activity.RESULT_OK, resultIntent);

    // Success with the transformed text is expected.
    verify(result).success(processedText);
  }

  @SuppressWarnings("deprecation")
  // setMessageHandler is deprecated.
  @Test
  public void doNotCrashOnNonRelatedActivityResult() {
    DartExecutor mockBinaryMessenger = mock(DartExecutor.class);
    PackageManager mockPackageManager = mock(PackageManager.class);
    ProcessTextChannel processTextChannel =
        new ProcessTextChannel(mockBinaryMessenger, mockPackageManager);

    // Set up mocked result for PackageManager.queryIntentActivities.
    ResolveInfo action1 = createFakeResolveInfo("Action1", mockPackageManager);
    ResolveInfo action2 = createFakeResolveInfo("Action2", mockPackageManager);
    List<ResolveInfo> infos = new ArrayList<ResolveInfo>(Arrays.asList(action1, action2));
    when(mockPackageManager.queryIntentActivities(
            any(Intent.class), any(PackageManager.ResolveInfoFlags.class)))
        .thenReturn(infos);

    // ProcessTextPlugin should retrieve the mocked text actions.
    ProcessTextPlugin processTextPlugin = new ProcessTextPlugin(processTextChannel);
    Map<String, String> textActions = processTextPlugin.queryTextActions();
    final String action1Id = "mockActivityName.Action1";
    final String action2Id = "mockActivityName.Action2";
    assertEquals(textActions, Map.of(action1Id, "Action1", action2Id, "Action2"));

    // Set up the activity binding.
    ActivityPluginBinding mockActivityPluginBinding = mock(ActivityPluginBinding.class);
    Activity mockActivity = mock(Activity.class);
    when(mockActivityPluginBinding.getActivity()).thenReturn(mockActivity);
    processTextPlugin.onAttachedToActivity(mockActivityPluginBinding);

    // Execute the first action.
    String textToBeProcessed = "Flutter!";
    MethodChannel.Result result = mock(MethodChannel.Result.class);
    processTextPlugin.processTextAction(action1Id, textToBeProcessed, false, result);

    // Activity.startActivityForResult should have been called.
    ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
    verify(mockActivity, times(1)).startActivityForResult(intentCaptor.capture(), anyInt());
    Intent intent = intentCaptor.getValue();
    assertEquals(intent.getStringExtra(Intent.EXTRA_PROCESS_TEXT), textToBeProcessed);

    // Result to a request not sent by this plugin should be ignored.
    final int externalRequestCode = 42;
    processTextPlugin.onActivityResult(externalRequestCode, Activity.RESULT_OK, new Intent());

    // Simulate an Android activity answer which returns a transformed text.
    String processedText = "Flutter!!!";
    Intent resultIntent = new Intent();
    resultIntent.putExtra(Intent.EXTRA_PROCESS_TEXT, processedText);
    processTextPlugin.onActivityResult(result.hashCode(), Activity.RESULT_OK, resultIntent);

    // Success with the transformed text is expected.
    verify(result).success(processedText);
  }

  private ResolveInfo createFakeResolveInfo(String label, PackageManager mockPackageManager) {
    ResolveInfo resolveInfo = mock(ResolveInfo.class);
    ActivityInfo activityInfo = new ActivityInfo();
    when(resolveInfo.loadLabel(mockPackageManager)).thenReturn(label);

    // Use Java reflection to set required member variables.
    try {
      Field activityField = ResolveInfo.class.getDeclaredField("activityInfo");
      activityField.setAccessible(true);
      activityField.set(resolveInfo, activityInfo);
      Field packageNameField = PackageItemInfo.class.getDeclaredField("packageName");
      packageNameField.setAccessible(true);
      packageNameField.set(activityInfo, "mockActivityPackageName");
      Field nameField = PackageItemInfo.class.getDeclaredField("name");
      nameField.setAccessible(true);
      nameField.set(activityInfo, "mockActivityName." + label);
    } catch (Exception ex) {
      // Test will failed if reflection APIs throw.
    }

    return resolveInfo;
  }
}
