// 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.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
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 android.view.inputmethod.InputMethodSubtype;
import io.flutter.Log;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;

class InputConnectionAdaptor extends BaseInputConnection {
  private final View mFlutterView;
  private final int mClient;
  private final TextInputChannel textInputChannel;
  private final Editable mEditable;
  private final EditorInfo mEditorInfo;
  private int mBatchCount;
  private InputMethodManager mImm;
  private final Layout mLayout;
  // Used to determine if Samsung-specific hacks should be applied.
  private final boolean isSamsung;

  private boolean mRepeatCheckNeeded = false;
  private TextEditingValue mLastSentTextEditngValue;
  // Data class used to get and store the last-sent values via updateEditingState to
  // the  framework. These are then compared against to prevent redundant messages
  // with the same data before any valid operations were made to the contents.
  private class TextEditingValue {
    public int selectionStart;
    public int selectionEnd;
    public int composingStart;
    public int composingEnd;
    public String text;

    public TextEditingValue(Editable editable) {
      selectionStart = Selection.getSelectionStart(editable);
      selectionEnd = Selection.getSelectionEnd(editable);
      composingStart = BaseInputConnection.getComposingSpanStart(editable);
      composingEnd = BaseInputConnection.getComposingSpanEnd(editable);
      text = editable.toString();
    }

    @Override
    public boolean equals(Object o) {
      if (o == this) {
        return true;
      }
      if (!(o instanceof TextEditingValue)) {
        return false;
      }
      TextEditingValue value = (TextEditingValue) o;
      return selectionStart == value.selectionStart
          && selectionEnd == value.selectionEnd
          && composingStart == value.composingStart
          && composingEnd == value.composingEnd
          && text.equals(value.text);
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + selectionStart;
      result = prime * result + selectionEnd;
      result = prime * result + composingStart;
      result = prime * result + composingEnd;
      result = prime * result + text.hashCode();
      return result;
    }
  }

  @SuppressWarnings("deprecation")
  public InputConnectionAdaptor(
      View view,
      int client,
      TextInputChannel textInputChannel,
      Editable editable,
      EditorInfo editorInfo) {
    super(view, true);
    mFlutterView = view;
    mClient = client;
    this.textInputChannel = textInputChannel;
    mEditable = editable;
    mEditorInfo = editorInfo;
    mBatchCount = 0;
    // 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);

    isSamsung = isSamsung();
  }

  // Send the current state of the editable to Flutter.
  private void updateEditingState() {
    // If the IME is in the middle of a batch edit, then wait until it completes.
    if (mBatchCount > 0) return;

    TextEditingValue currentValue = new TextEditingValue(mEditable);

    // Return if this data has already been sent and no meaningful changes have
    // occurred to mark this as dirty. This prevents duplicate remote updates of
    // the same data, which can break formatters that change the length of the
    // contents.
    if (mRepeatCheckNeeded && currentValue.equals(mLastSentTextEditngValue)) {
      return;
    }

    mImm.updateSelection(
        mFlutterView,
        currentValue.selectionStart,
        currentValue.selectionEnd,
        currentValue.composingStart,
        currentValue.composingEnd);

    textInputChannel.updateEditingState(
        mClient,
        currentValue.text,
        currentValue.selectionStart,
        currentValue.selectionEnd,
        currentValue.composingStart,
        currentValue.composingEnd);

    mRepeatCheckNeeded = true;
    mLastSentTextEditngValue = currentValue;
  }

  // This should be called whenever a change could have been made to
  // the value of mEditable, which will make any call of updateEditingState()
  // ineligible for repeat checking as we do not want to skip sending real changes
  // to the framework.
  public void markDirty() {
    // Disable updateEditngState's repeat-update check
    mRepeatCheckNeeded = false;
  }

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

  @Override
  public boolean beginBatchEdit() {
    mBatchCount++;
    return super.beginBatchEdit();
  }

  @Override
  public boolean endBatchEdit() {
    boolean result = super.endBatchEdit();
    mBatchCount--;
    updateEditingState();
    return result;
  }

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

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

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

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

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

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

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

    // Apply Samsung hacks. Samsung caches composing region data strangely, causing text
    // duplication.
    if (isSamsung) {
      if (Build.VERSION.SDK_INT >= 21) {
        // Samsung keyboards don't clear the composing region on finishComposingText.
        // Update the keyboard with a reset/empty composing region. Critical on
        // Samsung keyboards to prevent punctuation duplication.
        CursorAnchorInfo.Builder builder = new CursorAnchorInfo.Builder();
        builder.setComposingText(/*composingTextStart*/ -1, /*composingText*/ "");
        CursorAnchorInfo anchorInfo = builder.build();
        mImm.updateCursorAnchorInfo(mFlutterView, anchorInfo);
      }
    }

    markDirty();
    return result;
  }

  // TODO(garyq): Implement a more feature complete version of getExtractedText
  @Override
  public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
    ExtractedText extractedText = new ExtractedText();
    extractedText.selectionStart = Selection.getSelectionStart(mEditable);
    extractedText.selectionEnd = Selection.getSelectionEnd(mEditable);
    extractedText.text = mEditable.toString();
    return extractedText;
  }

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

  // Detect if the keyboard is a Samsung keyboard, where we apply Samsung-specific hacks to
  // fix critical bugs that make the keyboard otherwise unusable. See finishComposingText() for
  // more details.
  @SuppressLint("NewApi") // New API guard is inline, the linter can't see it.
  @SuppressWarnings("deprecation")
  private boolean isSamsung() {
    InputMethodSubtype subtype = mImm.getCurrentInputMethodSubtype();
    // Impacted devices all shipped with Android Lollipop or newer.
    if (subtype == null
        || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
        || !Build.MANUFACTURER.equals("samsung")) {
      return false;
    }
    String keyboardName =
        Settings.Secure.getString(
            mFlutterView.getContext().getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
    // The Samsung keyboard is called "com.sec.android.inputmethod/.SamsungKeypad" but look
    // for "Samsung" just in case Samsung changes the name of the keyboard.
    return keyboardName.contains("Samsung");
  }

  @Override
  public boolean setSelection(int start, int end) {
    boolean result = super.setSelection(start, end);
    markDirty();
    updateEditingState();
    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;
  }

  @Override
  public boolean sendKeyEvent(KeyEvent event) {
    markDirty();
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
      if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
        int selStart = clampIndexToEditable(Selection.getSelectionStart(mEditable), mEditable);
        int selEnd = clampIndexToEditable(Selection.getSelectionEnd(mEditable), mEditable);
        if (selEnd > selStart) {
          // Delete the selection.
          Selection.setSelection(mEditable, selStart);
          mEditable.delete(selStart, selEnd);
          updateEditingState();
          return true;
        } else if (selStart > 0) {
          // Delete to the left/right of the cursor depending on direction of text.
          // TODO(garyq): Explore how to obtain per-character direction. The
          // isRTLCharAt() call below is returning blanket direction assumption
          // based on the first character in the line.
          boolean isRtl = mLayout.isRtlCharAt(mLayout.getLineForOffset(selStart));
          try {
            if (isRtl) {
              Selection.extendRight(mEditable, mLayout);
            } else {
              Selection.extendLeft(mEditable, mLayout);
            }
          } catch (IndexOutOfBoundsException e) {
            // On some Chinese devices (primarily Huawei, some Xiaomi),
            // on initial app startup before focus is lost, the
            // Selection.extendLeft and extendRight calls always extend
            // from the index of the initial contents of mEditable. This
            // try-catch will prevent crashing on Huawei devices by falling
            // back to a simple way of deletion, although this a hack and
            // will not handle emojis.
            Selection.setSelection(mEditable, selStart, selStart - 1);
          }
          int newStart = clampIndexToEditable(Selection.getSelectionStart(mEditable), mEditable);
          int newEnd = clampIndexToEditable(Selection.getSelectionEnd(mEditable), mEditable);
          Selection.setSelection(mEditable, Math.min(newStart, newEnd));
          // Min/Max the values since RTL selections will start at a higher
          // index than they end at.
          mEditable.delete(Math.min(newStart, newEnd), Math.max(newStart, newEnd));
          updateEditingState();
          return true;
        }
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT) {
        int selStart = Selection.getSelectionStart(mEditable);
        int selEnd = Selection.getSelectionEnd(mEditable);
        if (selStart == selEnd && !event.isShiftPressed()) {
          int newSel = Math.max(selStart - 1, 0);
          setSelection(newSel, newSel);
        } else {
          int newSelEnd = Math.max(selEnd - 1, 0);
          setSelection(selStart, newSelEnd);
        }
        return true;
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT) {
        int selStart = Selection.getSelectionStart(mEditable);
        int selEnd = Selection.getSelectionEnd(mEditable);
        if (selStart == selEnd && !event.isShiftPressed()) {
          int newSel = Math.min(selStart + 1, mEditable.length());
          setSelection(newSel, newSel);
        } else {
          int newSelEnd = Math.min(selEnd + 1, mEditable.length());
          setSelection(selStart, newSelEnd);
        }
        return true;
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) {
        int selStart = Selection.getSelectionStart(mEditable);
        int selEnd = Selection.getSelectionEnd(mEditable);
        if (selStart == selEnd && !event.isShiftPressed()) {
          Selection.moveUp(mEditable, mLayout);
          int newSelStart = Selection.getSelectionStart(mEditable);
          setSelection(newSelStart, newSelStart);
        } else {
          Selection.extendUp(mEditable, mLayout);
          int newSelStart = Selection.getSelectionStart(mEditable);
          int newSelEnd = Selection.getSelectionEnd(mEditable);
          setSelection(newSelStart, newSelEnd);
        }
        return true;
      } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) {
        int selStart = Selection.getSelectionStart(mEditable);
        int selEnd = Selection.getSelectionEnd(mEditable);
        if (selStart == selEnd && !event.isShiftPressed()) {
          Selection.moveDown(mEditable, mLayout);
          int newSelStart = Selection.getSelectionStart(mEditable);
          setSelection(newSelStart, newSelStart);
        } else {
          Selection.extendDown(mEditable, mLayout);
          int newSelStart = Selection.getSelectionStart(mEditable);
          int newSelEnd = Selection.getSelectionEnd(mEditable);
          setSelection(newSelStart, newSelEnd);
        }
        return true;
        // 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.
        int character = event.getUnicodeChar();
        if (character != 0) {
          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, String.valueOf((char) character));
          setSelection(selMin + 1, selMin + 1);
        }
        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;
  }

  @Override
  public boolean performContextMenuAction(int id) {
    markDirty();
    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 performEditorAction(int actionCode) {
    markDirty();
    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;
  }
}
