// 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.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import android.view.textservice.TextServicesManager;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import io.flutter.embedding.engine.systemchannels.SpellCheckChannel;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.localization.LocalizationPlugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

/**
 * {@link SpellCheckPlugin} is the implementation of all functionality needed for spell check for
 * text input.
 *
 * <p>The plugin handles requests for spell check sent by the {@link
 * io.flutter.embedding.engine.systemchannels.SpellCheckChannel} via sending requests to the Android
 * spell checker. It also receives the spell check results from the service and sends them back to
 * the framework through the {@link io.flutter.embedding.engine.systemchannels.SpellCheckChannel}.
 */
public class SpellCheckPlugin
    implements SpellCheckChannel.SpellCheckMethodHandler,
        SpellCheckerSession.SpellCheckerSessionListener {

  private final SpellCheckChannel mSpellCheckChannel;
  private final TextServicesManager mTextServicesManager;
  private SpellCheckerSession mSpellCheckerSession;

  public static final String START_INDEX_KEY = "startIndex";
  public static final String END_INDEX_KEY = "endIndex";
  public static final String SUGGESTIONS_KEY = "suggestions";

  @VisibleForTesting MethodChannel.Result pendingResult;

  // The maximum number of suggestions that the Android spell check service is allowed to provide
  // per word. Same number that is used by default for Android's TextViews.
  private static final int MAX_SPELL_CHECK_SUGGESTIONS = 5;

  public SpellCheckPlugin(
      @NonNull TextServicesManager textServicesManager,
      @NonNull SpellCheckChannel spellCheckChannel) {
    mTextServicesManager = textServicesManager;
    mSpellCheckChannel = spellCheckChannel;

    mSpellCheckChannel.setSpellCheckMethodHandler(this);
  }

  /**
   * Unregisters this {@code SpellCheckPlugin} as the {@code
   * SpellCheckChannel.SpellCheckMethodHandler}, for the {@link
   * io.flutter.embedding.engine.systemchannels.SpellCheckChannel}, and closes the most recently
   * opened {@code SpellCheckerSession}.
   *
   * <p>Do not invoke any methods on a {@code SpellCheckPlugin} after invoking this method.
   */
  public void destroy() {
    mSpellCheckChannel.setSpellCheckMethodHandler(null);

    if (mSpellCheckerSession != null) {
      mSpellCheckerSession.close();
    }
  }

  /**
   * Initiates call to native spell checker to spell check specified text if there is no result
   * awaiting a response.
   */
  @Override
  public void initiateSpellCheck(
      @NonNull String locale, @NonNull String text, @NonNull MethodChannel.Result result) {
    if (pendingResult != null) {
      result.error("error", "Previous spell check request still pending.", null);
      return;
    }

    pendingResult = result;

    performSpellCheck(locale, text);
  }

  /** Calls on the Android spell check API to spell check specified text. */
  public void performSpellCheck(@NonNull String locale, @NonNull String text) {
    Locale localeFromString = LocalizationPlugin.localeFromString(locale);

    if (mSpellCheckerSession == null) {
      mSpellCheckerSession =
          mTextServicesManager.newSpellCheckerSession(
              null,
              localeFromString,
              this,
              /** referToSpellCheckerLanguageSettings= */
              true);
    }

    TextInfo[] textInfos = new TextInfo[] {new TextInfo(text)};
    mSpellCheckerSession.getSentenceSuggestions(textInfos, MAX_SPELL_CHECK_SUGGESTIONS);
  }

  /**
   * Callback for Android spell check API that decomposes results and send results through the
   * {@link SpellCheckChannel}.
   *
   * <p>Spell check results are encoded as dictionaries with a format that looks like
   *
   * <pre>{@code
   * {
   *   startIndex: 0,
   *   endIndex: 5,
   *   suggestions: [hello, ...]
   * }
   * }</pre>
   *
   * where there may be up to 5 suggestions.
   */
  @Override
  public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
    if (results.length == 0) {
      pendingResult.success(new ArrayList<HashMap<String, Object>>());
      pendingResult = null;
      return;
    }

    ArrayList<HashMap<String, Object>> spellCheckerSuggestionSpans =
        new ArrayList<HashMap<String, Object>>();
    SentenceSuggestionsInfo spellCheckResults = results[0];

    for (int i = 0; i < spellCheckResults.getSuggestionsCount(); i++) {
      SuggestionsInfo suggestionsInfo = spellCheckResults.getSuggestionsInfoAt(i);
      int suggestionsCount = suggestionsInfo.getSuggestionsCount();

      if (suggestionsCount <= 0) {
        continue;
      }

      HashMap<String, Object> spellCheckerSuggestionSpan = new HashMap<String, Object>();
      int start = spellCheckResults.getOffsetAt(i);
      int end = start + spellCheckResults.getLengthAt(i);

      spellCheckerSuggestionSpan.put(START_INDEX_KEY, start);
      spellCheckerSuggestionSpan.put(END_INDEX_KEY, end);

      ArrayList<String> suggestions = new ArrayList<String>();
      for (int j = 0; j < suggestionsCount; j++) {
        suggestions.add(suggestionsInfo.getSuggestionAt(j));
      }

      spellCheckerSuggestionSpan.put(SUGGESTIONS_KEY, suggestions);
      spellCheckerSuggestionSpans.add(spellCheckerSuggestionSpan);
    }

    pendingResult.success(spellCheckerSuggestionSpans);
    pendingResult = null;
  }

  @Override
  public void onGetSuggestions(SuggestionsInfo[] results) {
    // Deprecated callback for Android spell check API; will not use.
  }
}
