// 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.embedding.engine.systemchannels;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.Log;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.plugin.common.JSONMethodCodec;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import org.json.JSONArray;
import org.json.JSONException;

/**
 * {@link SpellCheckChannel} is a platform channel that is used by the framework to initiate spell
 * check in the embedding and for the embedding to send back the results.
 *
 * <p>When there is new text to be spell checked, the framework will send to the embedding the
 * message {@code SpellCheck.initiateSpellCheck} with the {@code String} locale to spell check with
 * and the {@code String} of text to spell check as arguments. In response, the {@link
 * io.flutter.plugin.editing.SpellCheckPlugin} will make a call to Android's spell check service to
 * fetch spell check results for the specified text.
 *
 * <p>Once the spell check results are received by the {@link
 * io.flutter.plugin.editing.SpellCheckPlugin}, it will send to the framework the message {@code
 * SpellCheck.updateSpellCheckResults} with the {@code ArrayList<String>} of encoded spell check
 * results (see {@link
 * io.flutter.plugin.editing.SpellCheckPlugin#onGetSentenceSuggestions(SentenceSuggestionsInfo[])}
 * for details) with the text that these results correspond to appeneded to the front as an
 * argument. For example, the argument may look like: {@code {"Hello, wrold!",
 * "7.11.world\nword\nold"}}.
 *
 * <p>{@link io.flutter.plugin.editing.SpellCheckPlugin} implements {@link SpellCheckMethodHandler}
 * to initiate spell check. Implement {@link SpellCheckMethodHandler} to respond to spell check
 * requests.
 */
public class SpellCheckChannel {
  private static final String TAG = "SpellCheckChannel";

  public final MethodChannel channel;
  private SpellCheckMethodHandler spellCheckMethodHandler;

  @NonNull
  public final MethodChannel.MethodCallHandler parsingMethodHandler =
      new MethodChannel.MethodCallHandler() {
        @Override
        public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
          if (spellCheckMethodHandler == null) {
            Log.v(
                TAG,
                "No SpellCheckeMethodHandler registered, call not forwarded to spell check API.");
            return;
          }
          String method = call.method;
          Object args = call.arguments;
          Log.v(TAG, "Received '" + method + "' message.");
          switch (method) {
            case "SpellCheck.initiateSpellCheck":
              try {
                final JSONArray argumentList = (JSONArray) args;
                String locale = argumentList.getString(0);
                String text = argumentList.getString(1);
                spellCheckMethodHandler.initiateSpellCheck(locale, text, result);
              } catch (JSONException exception) {
                result.error("error", exception.getMessage(), null);
              }
              break;
            default:
              result.notImplemented();
              break;
          }
        }
      };

  public SpellCheckChannel(@NonNull DartExecutor dartExecutor) {
    channel = new MethodChannel(dartExecutor, "flutter/spellcheck", JSONMethodCodec.INSTANCE);
    channel.setMethodCallHandler(parsingMethodHandler);
  }

  /**
   * Sets the {@link SpellCheckMethodHandler} which receives all requests to spell check the
   * specified text sent through this channel.
   */
  public void setSpellCheckMethodHandler(
      @Nullable SpellCheckMethodHandler spellCheckMethodHandler) {
    this.spellCheckMethodHandler = spellCheckMethodHandler;
  }

  public interface SpellCheckMethodHandler {
    /**
     * Requests that spell check is initiated for the specified text, which will respond to the
     * {@code result} with either success if spell check results are received or error if the
     * request is skipped.
     */
    void initiateSpellCheck(
        @NonNull String locale, @NonNull String text, @NonNull MethodChannel.Result result);
  }
}

@@ -1297,24 +1297,29 @@
 t will send 
+back 
 to the frame
@@ -1327,24 +1327,16 @@
 ork the 
-message 
 %7B@code%0A 
@@ -1340,60 +1340,8 @@
 e%0A *
- SpellCheck.updateSpellCheckResults%7D with the %7B@code
  Arr
@@ -1378,19 +1378,16 @@
 ll check
-%0A *
  results
@@ -1473,39 +1473,9 @@
 ions
-(SentenceSuggestionsInfo%5B%5D)%7D%0A *
+%7D
  for
@@ -1497,16 +1497,19 @@
 the text
+%0A *
  that th
@@ -1539,17 +1539,16 @@
 to appen
-e
 ded to t
@@ -1561,19 +1561,16 @@
 nt as an
-%0A *
  argumen
@@ -1597,16 +1597,19 @@
 argument
+%0A *
  may loo
@@ -1640,19 +1640,16 @@
 wrold!%22,
-%0A *
  %227.11.w
@@ -1667,16 +1667,229 @@
 nold%22%7D%7D.
+ The %7B@link%0A * io.flutter.plugin.editing.SpellCheckPlugin%7D only handles one request to fetch spell check results%0A * at a time; see %7B@link io.flutter.plugin.editing.SpellCheckPlugin#initiateSpellCheck%7D for details.
 %0A *%0A * %3C

Correct SpellCheckChannel Javadoc (#33398)