// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package io.flutter.plugin.editing;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.InputType;
import android.text.Layout;
import android.text.Selection;
import android.text.TextPaint;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CursorAnchorInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputMethodManager;
import io.flutter.Log;
import io.flutter.embedding.android.AndroidKeyProcessor;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;

class InputConnectionAdaptor extends BaseInputConnection
    implements ListenableEditingState.EditingStateWatcher {
  private static final String TAG = "InputConnectionAdaptor";

  private final View mFlutterView;
  private final int mClient;
  private final TextInputChannel textInputChannel;
  private final AndroidKeyProcessor keyProcessor;
  private final ListenableEditingState mEditable;
  private final EditorInfo mEditorInfo;
  private ExtractedTextRequest mExtractRequest;
  private boolean mMonitorCursorUpdate = false;
  private CursorAnchorInfo.Builder mCursorAnchorInfoBuilder;
  private ExtractedText mExtractedText = new ExtractedText();
  private InputMethodManager mImm;
  private final Layout mLayout;
  private FlutterTextUtils flutterTextUtils;
  private int batchEditNestDepth = 0;

  @SuppressWarnings("deprecation")
  public InputConnectionAdaptor(
      View view,
      int client,
      TextInputChannel textInputChannel,
      AndroidKeyProcessor keyProcessor,
      ListenableEditingState editable,
      EditorInfo editorInfo,
      FlutterJNI flutterJNI) {
    super(view, true);
    mFlutterView = view;
    mClient = client;
    this.textInputChannel = textInputChannel;
    mEditable = editable;
    mEditable.addEditingStateListener(this);
    mEditorInfo = editorInfo;
    this.keyProcessor = keyProcessor;
    this.flutterTextUtils = new FlutterTextUtils(flutterJNI);
    // We create a dummy Layout with max width so that the selection
    // shifting acts as if all text were in one line.
    mLayout =
        new DynamicLayout(
            mEditable,
            new TextPaint(),
            Integer.MAX_VALUE,
            Layout.Alignment.ALIGN_NORMAL,
            1.0f,
            0.0f,
            false);
    mImm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
  }

  public InputConnectionAdaptor(
      View view,
      int client,
      TextInputChannel textInputChannel,
      AndroidKeyProcessor keyProcessor,
      ListenableEditingState editable,
      EditorInfo editorInfo) {
    this(view, client, textInputChannel, keyProcessor, editable, editorInfo, new FlutterJNI());
  }

  private ExtractedText getExtractedText(ExtractedTextRequest request) {
    mExtractedText.startOffset = 0;
    mExtractedText.partialStartOffset = -1;
    mExtractedText.partialEndOffset = -1;
    mExtractedText.selectionStart = mEditable.getSelectionStart();
    mExtractedText.selectionEnd = mEditable.getSelectionEnd();
    mExtractedText.text =
        request == null || (request.flags & GET_TEXT_WITH_STYLES) == 0
            ? mEditable.toString()
            : mEditable;
    return mExtractedText;
  }

  private CursorAnchorInfo getCursorAnchorInfo() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
      return null;
    }
    if (mCursorAnchorInfoBuilder == null) {
      mCursorAnchorInfoBuilder = new CursorAnchorInfo.Builder();
    } else {
      mCursorAnchorInfoBuilder.reset();
    }

    mCursorAnchorInfoBuilder.setSelectionRange(
        mEditable.getSelectionStart(), mEditable.getSelectionEnd());
    final int composingStart = mEditable.getComposingStart();
    final int composingEnd = mEditable.getComposingEnd();
    if (composingStart >= 0 && composingEnd > composingStart) {
      mCursorAnchorInfoBuilder.setComposingText(
          composingStart, mEditable.toString().subSequence(composingStart, composingEnd));
    } else {
      mCursorAnchorInfoBuilder.setComposingText(-1, "");
    }
    return mCursorAnchorInfoBuilder.build();
  }

  @Override
  public Editable getEditable() {
    return mEditable;
  }

  @Override
  public boolean beginBatchEdit() {
    mEditable.beginBatchEdit();
    batchEditNestDepth += 1;
    return super.beginBatchEdit();
  }

  @Override
  public boolean endBatchEdit() {
    boolean result = super.endBatchEdit();
    batchEditNestDepth -= 1;
    mEditable.endBatchEdit();
    return result;
  }

  @Override
  public boolean commitText(CharSequence text, int newCursorPosition) {
    final boolean result = super.commitText(text, newCursorPosition);
    return result;
  }

  @Override
  public boolean deleteSurroundingText(int beforeLength, int afterLength) {
    if (mEditable.getSelectionStart() == -1) {
      return true;
    }

    final boolean result = super.deleteSurroundingText(beforeLength, afterLength);
    return result;
  }

  @Override
  public boolean deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
    boolean result = super.deleteSurroundingTextInCodePoints(beforeLength, afterLength);
    return result;
  }

  @Override
  public boolean setComposingRegion(int start, int end) {
    final boolean result = super.setComposingRegion(start, end);
    return result;
  }

  @Override
  public boolean setComposingText(CharSequence text, int newCursorPosition) {
    boolean result;
    beginBatchEdit();
    if (text.length() == 0) {
      result = super.commitText(text, newCursorPosition);
    } else {
      result = super.setComposingText(text, newCursorPosition);
    }
    endBatchEdit();
    return result;
  }

  @Override
  public boolean finishComposingText() {
    final boolean result = super.finishComposingText();
    return result;
  }

  // When there's not enough vertical screen space, the IME may enter fullscreen mode and this
  // method will be used to get (a portion of) the currently edited text. Samsung keyboard seems
  // to use this method instead of InputConnection#getText{Before,After}Cursor.
  // See https://github.com/flutter/engine/pull/17426.
  // TODO(garyq): Implement a more feature complete version of getExtractedText
  @Override
  public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    final boolean textMonitor = (flags & GET_EXTRACTED_TEXT_MONITOR) != 0;
    if (textMonitor == (mExtractRequest == null)) {
      Log.d(TAG, "The input method toggled text monitoring " + (textMonitor ? "on" : "off"));
    }
    // Enables text monitoring if the relevant flag is set. See
    // InputConnectionAdaptor#didChangeEditingState.
    mExtractRequest = textMonitor ? request : null;
    return getExtractedText(request);
  }

  @Override
  public boolean requestCursorUpdates(int cursorUpdateMode) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
      return false;
    }
    if ((cursorUpdateMode & CURSOR_UPDATE_IMMEDIATE) != 0) {
      mImm.updateCursorAnchorInfo(mFlutterView, getCursorAnchorInfo());
    }

    final boolean updated = (cursorUpdateMode & CURSOR_UPDATE_MONITOR) != 0;
    if (updated != mMonitorCursorUpdate) {
      Log.d(TAG, "The input method toggled cursor monitoring " + (updated ? "on" : "off"));
    }

    // Enables cursor monitoring. See InputConnectionAdaptor#didChangeEditingState.
    mMonitorCursorUpdate = updated;
    return true;
  }

  @Override
  public boolean clearMetaKeyStates(int states) {
    boolean result = super.clearMetaKeyStates(states);
    return result;
  }

  @Override
  public void closeConnection() {
    super.closeConnection();
    mEditable.removeEditingStateListener(this);
    for (; batchEditNestDepth > 0; batchEditNestDepth--) {
      endBatchEdit();
    }
  }

  @Override
  public boolean setSelection(int start, int end) {
    beginBatchEdit();
    boolean result = super.setSelection(start, end);
    endBatchEdit();
    return result;
  }

  // Sanitizes the index to ensure the index is within the range of the
  // contents of editable.
  private static int clampIndexToEditable(int index, Editable editable) {
    int clamped = Math.max(0, Math.min(editable.length(), index));
    if (clamped != index) {
      Log.d(
          "flutter",
          "Text selection index was clamped ("
              + index
              + "->"
              + clamped
              + ") to remain in bounds. This may not be your fault, as some keyboards may select outside of bounds.");
    }
    return clamped;
  }

  // This function is called both when hardware key events occur and aren't
  // handled by the framework, as well as when soft keyboard editing events
  // occur, and need a chance to be handled by the framework.
  @Override
  public boolean sendKeyEvent(KeyEvent event) {
    // This gives the key processor a chance to process this event if it came
    // from a soft keyboard. It will send it to the framework to be handled and
    // return true. If the framework ends up not handling it, the processor will
    // re-send the event to this function. Only do this if the event is not the
    // current event, since that indicates that the key processor sent it to us,
    // and we only want to call the key processor for events that it doesn't
    // already know about (i.e. when events arrive here from a soft keyboard and
    // not a hardware keyboard), to avoid a loop.
    if (keyProcessor != null
        && !keyProcessor.isPendingEvent(event)
        && keyProcessor.onKeyEvent(event)) {
      return true;
    }

    if (event.getAction() == KeyEvent.ACTION_DOWN) {
      if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) {
        return handleHorizontalMovement(true, event.isShiftPressed());
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) {
        return handleHorizontalMovement(false, event.isShiftPressed());
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
        return handleVerticalMovement(true, event.isShiftPressed());
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
        return handleVerticalMovement(false, event.isShiftPressed());
        // When the enter key is pressed on a non-multiline field, consider it a
        // submit instead of a newline.
      } else if ((event.getKeyCode() == KeyEvent.KEYCODE_ENTER
              || event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER)
          && (InputType.TYPE_TEXT_FLAG_MULTI_LINE & mEditorInfo.inputType) == 0) {
        performEditorAction(mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION);
        return true;
      } else {
        // Enter a character.
        final int selStart = Selection.getSelectionStart(mEditable);
        final int selEnd = Selection.getSelectionEnd(mEditable);
        final int character = event.getUnicodeChar();
        if (selStart < 0 || selEnd < 0 || character == 0) {
          return false;
        }

        final int selMin = Math.min(selStart, selEnd);
        final int selMax = Math.max(selStart, selEnd);
        beginBatchEdit();
        if (selMin != selMax) mEditable.delete(selMin, selMax);
        mEditable.insert(selMin, String.valueOf((char) character));
        setSelection(selMin + 1, selMin + 1);
        endBatchEdit();
        return true;
      }
    }
    if (event.getAction() == KeyEvent.ACTION_UP
        && (event.getKeyCode() == KeyEvent.KEYCODE_SHIFT_LEFT
            || event.getKeyCode() == KeyEvent.KEYCODE_SHIFT_RIGHT)) {
      int selEnd = Selection.getSelectionEnd(mEditable);
      setSelection(selEnd, selEnd);
      return true;
    }
    return false;
  }

  private boolean handleHorizontalMovement(boolean isLeft, boolean isShiftPressed) {
    final int selStart = Selection.getSelectionStart(mEditable);
    final int selEnd = Selection.getSelectionEnd(mEditable);

    if (selStart < 0 || selEnd < 0) {
      return false;
    }

    final int newSelectionEnd =
        isLeft
            ? Math.max(flutterTextUtils.getOffsetBefore(mEditable, selEnd), 0)
            : Math.min(flutterTextUtils.getOffsetAfter(mEditable, selEnd), mEditable.length());

    final boolean shouldCollapse = selStart == selEnd && !isShiftPressed;

    if (shouldCollapse) {
      setSelection(newSelectionEnd, newSelectionEnd);
    } else {
      setSelection(selStart, newSelectionEnd);
    }
    return true;
  };

  private boolean handleVerticalMovement(boolean isUp, boolean isShiftPressed) {
    final int selStart = Selection.getSelectionStart(mEditable);
    final int selEnd = Selection.getSelectionEnd(mEditable);

    if (selStart < 0 || selEnd < 0) {
      return false;
    }

    final boolean shouldCollapse = selStart == selEnd && !isShiftPressed;

    beginBatchEdit();
    if (shouldCollapse) {
      if (isUp) {
        Selection.moveUp(mEditable, mLayout);
      } else {
        Selection.moveDown(mEditable, mLayout);
      }
      final int newSelection = Selection.getSelectionStart(mEditable);
      setSelection(newSelection, newSelection);
    } else {
      if (isUp) {
        Selection.extendUp(mEditable, mLayout);
      } else {
        Selection.extendDown(mEditable, mLayout);
      }
      setSelection(Selection.getSelectionStart(mEditable), Selection.getSelectionEnd(mEditable));
    }
    endBatchEdit();
    return true;
  }

  @Override
  public boolean performContextMenuAction(int id) {
    beginBatchEdit();
    final boolean result = doPerformContextMenuAction(id);
    endBatchEdit();
    return result;
  }

  private boolean doPerformContextMenuAction(int id) {
    if (id == android.R.id.selectAll) {
      setSelection(0, mEditable.length());
      return true;
    } else if (id == android.R.id.cut) {
      int selStart = Selection.getSelectionStart(mEditable);
      int selEnd = Selection.getSelectionEnd(mEditable);
      if (selStart != selEnd) {
        int selMin = Math.min(selStart, selEnd);
        int selMax = Math.max(selStart, selEnd);
        CharSequence textToCut = mEditable.subSequence(selMin, selMax);
        ClipboardManager clipboard =
            (ClipboardManager)
                mFlutterView.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("text label?", textToCut);
        clipboard.setPrimaryClip(clip);
        mEditable.delete(selMin, selMax);
        setSelection(selMin, selMin);
      }
      return true;
    } else if (id == android.R.id.copy) {
      int selStart = Selection.getSelectionStart(mEditable);
      int selEnd = Selection.getSelectionEnd(mEditable);
      if (selStart != selEnd) {
        CharSequence textToCopy =
            mEditable.subSequence(Math.min(selStart, selEnd), Math.max(selStart, selEnd));
        ClipboardManager clipboard =
            (ClipboardManager)
                mFlutterView.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
        clipboard.setPrimaryClip(ClipData.newPlainText("text label?", textToCopy));
      }
      return true;
    } else if (id == android.R.id.paste) {
      ClipboardManager clipboard =
          (ClipboardManager) mFlutterView.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
      ClipData clip = clipboard.getPrimaryClip();
      if (clip != null) {
        CharSequence textToPaste = clip.getItemAt(0).coerceToText(mFlutterView.getContext());
        int selStart = Math.max(0, Selection.getSelectionStart(mEditable));
        int selEnd = Math.max(0, Selection.getSelectionEnd(mEditable));
        int selMin = Math.min(selStart, selEnd);
        int selMax = Math.max(selStart, selEnd);
        if (selMin != selMax) mEditable.delete(selMin, selMax);
        mEditable.insert(selMin, textToPaste);
        int newSelStart = selMin + textToPaste.length();
        setSelection(newSelStart, newSelStart);
      }
      return true;
    }
    return false;
  }

  @Override
  public boolean performPrivateCommand(String action, Bundle data) {
    textInputChannel.performPrivateCommand(mClient, action, data);
    return true;
  }

  @Override
  public boolean performEditorAction(int actionCode) {
    switch (actionCode) {
      case EditorInfo.IME_ACTION_NONE:
        textInputChannel.newline(mClient);
        break;
      case EditorInfo.IME_ACTION_UNSPECIFIED:
        textInputChannel.unspecifiedAction(mClient);
        break;
      case EditorInfo.IME_ACTION_GO:
        textInputChannel.go(mClient);
        break;
      case EditorInfo.IME_ACTION_SEARCH:
        textInputChannel.search(mClient);
        break;
      case EditorInfo.IME_ACTION_SEND:
        textInputChannel.send(mClient);
        break;
      case EditorInfo.IME_ACTION_NEXT:
        textInputChannel.next(mClient);
        break;
      case EditorInfo.IME_ACTION_PREVIOUS:
        textInputChannel.previous(mClient);
        break;
      default:
      case EditorInfo.IME_ACTION_DONE:
        textInputChannel.done(mClient);
        break;
    }
    return true;
  }

  // -------- Start: ListenableEditingState watcher implementation -------
  @Override
  public void didChangeEditingState(
      boolean textChanged, boolean selectionChanged, boolean composingRegionChanged) {
    // This method notifies the input method that the editing state has changed.
    // updateSelection is mandatory. updateExtractedText and updateCursorAnchorInfo
    // are on demand (if the input method set the correspoinding monitoring
    // flags). See getExtractedText and requestCursorUpdates.

    // Always send selection update. InputMethodManager#updateSelection skips
    // sending the message if none of the parameters have changed since the last
    // time we called it.
    mImm.updateSelection(
        mFlutterView,
        mEditable.getSelectionStart(),
        mEditable.getSelectionEnd(),
        mEditable.getComposingStart(),
        mEditable.getComposingEnd());

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
      return;
    }
    if (mExtractRequest != null) {
      mImm.updateExtractedText(
          mFlutterView, mExtractRequest.token, getExtractedText(mExtractRequest));
    }
    if (mMonitorCursorUpdate) {
      final CursorAnchorInfo info = getCursorAnchorInfo();
      mImm.updateCursorAnchorInfo(mFlutterView, info);
    }
  }
  // -------- End: ListenableEditingState watcher implementation -------
}
