package io.flutter.plugin.editing;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;

import android.content.Context;
import android.text.Editable;
import android.text.Selection;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import io.flutter.embedding.android.KeyboardManager;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import java.util.ArrayList;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;

@Config(manifest = Config.NONE)
@RunWith(AndroidJUnit4.class)
public class ListenableEditingStateTest {
  private final Context ctx = ApplicationProvider.getApplicationContext();
  @Mock KeyboardManager mockKeyboardManager;

  private BaseInputConnection getTestInputConnection(View view, Editable mEditable) {
    new View(ctx);
    return new BaseInputConnection(view, true) {
      @Override
      public Editable getEditable() {
        return mEditable;
      }
    };
  }

  @Before
  public void setUp() {
    MockitoAnnotations.openMocks(this);
  }

  @Test
  public void testConstructor() {
    // When provided valid composing range, should not fail
    new ListenableEditingState(
        new TextInputChannel.TextEditState("hello", 1, 4, 1, 4), new View(ctx));
  }

  // -------- Start: Test BatchEditing   -------
  @Test
  public void testBatchEditing() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();
    final View testView = new View(ctx);
    final BaseInputConnection inputConnection = getTestInputConnection(testView, editingState);

    editingState.addEditingStateListener(listener);

    editingState.replace(0, editingState.length(), "update");
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    assertFalse(listener.selectionChanged);
    assertFalse(listener.composingRegionChanged);

    assertEquals(-1, editingState.getSelectionStart());
    assertEquals(-1, editingState.getSelectionEnd());

    listener.reset();

    // Batch edit depth = 1.
    editingState.beginBatchEdit();
    editingState.replace(0, editingState.length(), "update1");
    assertFalse(listener.isCalled());
    // Batch edit depth = 2.
    editingState.beginBatchEdit();
    editingState.replace(0, editingState.length(), "update2");
    inputConnection.setComposingRegion(0, editingState.length());
    assertFalse(listener.isCalled());
    // Batch edit depth = 1.
    editingState.endBatchEdit();
    assertFalse(listener.isCalled());

    // Batch edit depth = 2.
    editingState.beginBatchEdit();
    assertFalse(listener.isCalled());
    inputConnection.setSelection(0, 0);
    assertFalse(listener.isCalled());
    // Batch edit depth = 1.
    editingState.endBatchEdit();
    assertFalse(listener.isCalled());

    // Remove composing region.
    inputConnection.finishComposingText();

    // Batch edit depth = 0. Last endBatchEdit.
    editingState.endBatchEdit();

    // Now notify the listener.
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    assertFalse(listener.composingRegionChanged);
  }

  @Test
  public void testBatchingEditing_callEndBeforeBegin() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();
    editingState.addEditingStateListener(listener);

    editingState.endBatchEdit();
    assertFalse(listener.isCalled());

    editingState.replace(0, editingState.length(), "text");
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);

    listener.reset();
    // Does not disrupt the followup events.
    editingState.beginBatchEdit();
    editingState.replace(0, editingState.length(), "more text");
    assertFalse(listener.isCalled());
    editingState.endBatchEdit();
    assertTrue(listener.isCalled());
  }

  @Test
  public void testBatchingEditing_addListenerDuringBatchEdit() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();

    editingState.beginBatchEdit();
    editingState.addEditingStateListener(listener);
    editingState.replace(0, editingState.length(), "update");
    editingState.endBatchEdit();

    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    assertTrue(listener.selectionChanged);
    assertTrue(listener.composingRegionChanged);

    listener.reset();

    // Verifies the listener is officially added.
    editingState.replace(0, editingState.length(), "more updates");
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    editingState.removeEditingStateListener(listener);

    listener.reset();
    // Now remove before endBatchEdit();
    editingState.beginBatchEdit();
    editingState.addEditingStateListener(listener);
    editingState.replace(0, editingState.length(), "update");
    editingState.removeEditingStateListener(listener);
    editingState.endBatchEdit();

    assertFalse(listener.isCalled());
  }

  @Test
  public void testBatchingEditing_removeListenerDuringBatchEdit() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();
    editingState.addEditingStateListener(listener);

    editingState.beginBatchEdit();
    editingState.replace(0, editingState.length(), "update");
    editingState.removeEditingStateListener(listener);
    editingState.endBatchEdit();

    assertFalse(listener.isCalled());
  }

  @Test
  public void testBatchingEditing_listenerCallsReplaceWhenBatchEditEnds() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));

    final Listener listener =
        new Listener() {
          @Override
          public void didChangeEditingState(
              boolean textChanged, boolean selectionChanged, boolean composingRegionChanged) {
            super.didChangeEditingState(textChanged, selectionChanged, composingRegionChanged);
            editingState.replace(
                0, editingState.length(), "one does not simply replace the text in the listener");
          }
        };
    editingState.addEditingStateListener(listener);

    editingState.beginBatchEdit();
    editingState.replace(0, editingState.length(), "update");
    editingState.endBatchEdit();

    assertTrue(listener.isCalled());
    assertEquals(1, listener.timesCalled);
    assertEquals("one does not simply replace the text in the listener", editingState.toString());
  }
  // -------- End: Test BatchEditing   -------

  @Test
  public void testSetComposingRegion() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    editingState.replace(0, editingState.length(), "text");

    // (-1, -1) clears the composing region.
    editingState.setComposingRange(-1, -1);
    assertEquals(-1, editingState.getComposingStart());
    assertEquals(-1, editingState.getComposingEnd());

    editingState.setComposingRange(-1, 5);
    assertEquals(-1, editingState.getComposingStart());
    assertEquals(-1, editingState.getComposingEnd());

    editingState.setComposingRange(2, 3);
    assertEquals(2, editingState.getComposingStart());
    assertEquals(3, editingState.getComposingEnd());

    // Empty range is invalid. Clears composing region.
    editingState.setComposingRange(1, 1);
    assertEquals(-1, editingState.getComposingStart());
    assertEquals(-1, editingState.getComposingEnd());

    // Covers everything.
    editingState.setComposingRange(0, editingState.length());
    assertEquals(0, editingState.getComposingStart());
    assertEquals(editingState.length(), editingState.getComposingEnd());
  }

  @Test
  public void testClearBatchDeltas() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    editingState.replace(0, editingState.length(), "text");
    editingState.delete(0, 1);
    editingState.insert(0, "This is t");
    editingState.clearBatchDeltas();
    assertEquals(0, editingState.extractBatchTextEditingDeltas().size());
  }

  @Test
  public void testExtractBatchTextEditingDeltas() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));

    // Creating some deltas.
    editingState.replace(0, editingState.length(), "test");
    editingState.delete(0, 1);
    editingState.insert(0, "This is a t");

    ArrayList<TextEditingDelta> batchDeltas = editingState.extractBatchTextEditingDeltas();
    assertEquals(3, batchDeltas.size());
  }

  // -------- Start: Test InputMethods actions   -------
  @Test
  public void inputMethod_batchEditingBeginAndEnd() {
    final ArrayList<String> batchMarkers = new ArrayList<>();
    final ListenableEditingState editingState =
        new ListenableEditingState(null, new View(ctx)) {
          @Override
          public final void beginBatchEdit() {
            super.beginBatchEdit();
            batchMarkers.add("begin");
          }

          @Override
          public void endBatchEdit() {
            super.endBatchEdit();
            batchMarkers.add("end");
          }
        };

    final Listener listener = new Listener();
    final View testView = new View(ctx);
    final InputConnectionAdaptor inputConnection =
        new InputConnectionAdaptor(
            testView,
            0,
            mock(TextInputChannel.class),
            mockKeyboardManager,
            editingState,
            new EditorInfo());

    // Make sure begin/endBatchEdit is called on the Editable when the input method calls
    // InputConnection#begin/endBatchEdit.
    inputConnection.beginBatchEdit();
    assertEquals(1, batchMarkers.size());
    assertEquals("begin", batchMarkers.get(0));

    inputConnection.endBatchEdit();
    assertEquals(2, batchMarkers.size());
    assertEquals("end", batchMarkers.get(1));
  }

  @Test
  public void inputMethod_testSetSelection() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();
    final View testView = new View(ctx);
    final InputConnectionAdaptor inputConnection =
        new InputConnectionAdaptor(
            testView,
            0,
            mock(TextInputChannel.class),
            mockKeyboardManager,
            editingState,
            new EditorInfo());
    editingState.replace(0, editingState.length(), "initial text");

    editingState.addEditingStateListener(listener);

    inputConnection.setSelection(0, 0);

    assertTrue(listener.isCalled());
    assertFalse(listener.textChanged);
    assertTrue(listener.selectionChanged);
    assertFalse(listener.composingRegionChanged);

    listener.reset();

    inputConnection.setSelection(5, 5);

    assertTrue(listener.isCalled());
    assertFalse(listener.textChanged);
    assertTrue(listener.selectionChanged);
    assertFalse(listener.composingRegionChanged);
  }

  @Test
  public void inputMethod_testSetComposition() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();
    final View testView = new View(ctx);
    final InputConnectionAdaptor inputConnection =
        new InputConnectionAdaptor(
            testView,
            0,
            mock(TextInputChannel.class),
            mockKeyboardManager,
            editingState,
            new EditorInfo());
    editingState.replace(0, editingState.length(), "initial text");

    editingState.addEditingStateListener(listener);

    // setComposingRegion test.
    inputConnection.setComposingRegion(1, 3);
    assertTrue(listener.isCalled());
    assertFalse(listener.textChanged);
    assertFalse(listener.selectionChanged);
    assertTrue(listener.composingRegionChanged);

    Selection.setSelection(editingState, 0, 0);
    listener.reset();

    // setComposingText test: non-empty text, does not move cursor.
    inputConnection.setComposingText("composing", -1);
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    assertFalse(listener.selectionChanged);
    assertTrue(listener.composingRegionChanged);

    listener.reset();
    // setComposingText test: non-empty text, moves cursor.
    inputConnection.setComposingText("composing2", 1);
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    assertTrue(listener.selectionChanged);
    assertTrue(listener.composingRegionChanged);

    listener.reset();
    // setComposingText test: empty text.
    inputConnection.setComposingText("", 1);
    assertTrue(listener.isCalled());
    assertTrue(listener.textChanged);
    assertTrue(listener.selectionChanged);
    assertTrue(listener.composingRegionChanged);

    // finishComposingText test.
    inputConnection.setComposingText("composing text", 1);
    listener.reset();
    inputConnection.finishComposingText();
    assertTrue(listener.isCalled());
    assertFalse(listener.textChanged);
    assertFalse(listener.selectionChanged);
    assertTrue(listener.composingRegionChanged);
  }

  @Test
  public void inputMethod_testCommitText() {
    final ListenableEditingState editingState = new ListenableEditingState(null, new View(ctx));
    final Listener listener = new Listener();
    final View testView = new View(ctx);
    final InputConnectionAdaptor inputConnection =
        new InputConnectionAdaptor(
            testView,
            0,
            mock(TextInputChannel.class),
            mockKeyboardManager,
            editingState,
            new EditorInfo());
    editingState.replace(0, editingState.length(), "initial text");

    editingState.addEditingStateListener(listener);
  }
  // -------- End: Test InputMethods actions   -------

  public static class Listener implements ListenableEditingState.EditingStateWatcher {
    public boolean isCalled() {
      return timesCalled > 0;
    }

    int timesCalled = 0;
    boolean textChanged = false;
    boolean selectionChanged = false;
    boolean composingRegionChanged = false;

    @Override
    public void didChangeEditingState(
        boolean textChanged, boolean selectionChanged, boolean composingRegionChanged) {
      timesCalled++;
      this.textChanged = textChanged;
      this.selectionChanged = selectionChanged;
      this.composingRegionChanged = composingRegionChanged;
    }

    public void reset() {
      timesCalled = 0;
      textChanged = false;
      selectionChanged = false;
      composingRegionChanged = false;
    }
  }
}
