// Copyright 2019 The Chromium 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 androidx.test.espresso.flutter;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.flutter.common.Constants.DEFAULT_INTERACTION_TIMEOUT;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.isFlutterView;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.hamcrest.Matchers.any;

import android.util.Log;
import android.view.View;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.flutter.action.FlutterViewAction;
import androidx.test.espresso.flutter.action.WidgetInfoFetcher;
import androidx.test.espresso.flutter.api.FlutterAction;
import androidx.test.espresso.flutter.api.WidgetAction;
import androidx.test.espresso.flutter.api.WidgetAssertion;
import androidx.test.espresso.flutter.api.WidgetMatcher;
import androidx.test.espresso.flutter.assertion.FlutterViewAssertion;
import androidx.test.espresso.flutter.common.Duration;
import androidx.test.espresso.flutter.exception.NoMatchingWidgetException;
import androidx.test.espresso.flutter.internal.idgenerator.IdGenerator;
import androidx.test.espresso.flutter.internal.idgenerator.IdGenerators;
import androidx.test.espresso.flutter.model.WidgetInfo;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.annotation.Nonnull;
import okhttp3.OkHttpClient;
import org.hamcrest.Matcher;

/** Entry point to the Espresso testing APIs on Flutter. */
public final class EspressoFlutter {

  private static final String TAG = EspressoFlutter.class.getSimpleName();

  private static final OkHttpClient okHttpClient;
  private static final IdGenerator<Integer> idGenerator;
  private static final ExecutorService taskExecutor;

  static {
    okHttpClient = new OkHttpClient();
    idGenerator = IdGenerators.newIntegerIdGenerator();
    taskExecutor = Executors.newCachedThreadPool();
  }

  /**
   * Creates a {@link WidgetInteraction} for the Flutter widget matched by the given {@code
   * widgetMatcher}, which is an entry point to perform actions or asserts.
   *
   * @param widgetMatcher the matcher used to uniquely match a Flutter widget on the screen.
   */
  public static WidgetInteraction onFlutterWidget(@Nonnull WidgetMatcher widgetMatcher) {
    return new WidgetInteraction(isFlutterView(), widgetMatcher);
  }

  /**
   * Provides fluent testing APIs for test authors to perform actions or asserts on Flutter widgets,
   * similar to {@code ViewInteraction} and {@code WebInteraction}.
   */
  public static final class WidgetInteraction {

    /**
     * Adds a little delay to the interaction timeout so that we make sure not to time out before
     * the action or assert does.
     */
    private static final Duration INTERACTION_TIMEOUT_DELAY = new Duration(1, TimeUnit.SECONDS);

    private final Matcher<View> flutterViewMatcher;
    private final WidgetMatcher widgetMatcher;
    private final Duration timeout;

    private WidgetInteraction(Matcher<View> flutterViewMatcher, WidgetMatcher widgetMatcher) {
      this(
          flutterViewMatcher,
          widgetMatcher,
          DEFAULT_INTERACTION_TIMEOUT.plus(INTERACTION_TIMEOUT_DELAY));
    }

    private WidgetInteraction(
        Matcher<View> flutterViewMatcher, WidgetMatcher widgetMatcher, Duration timeout) {
      this.flutterViewMatcher = checkNotNull(flutterViewMatcher);
      this.widgetMatcher = checkNotNull(widgetMatcher);
      this.timeout = checkNotNull(timeout);
    }

    /**
     * Executes the given action(s) with synchronization guarantees: Espresso ensures Flutter's in
     * an idle state before interacting with the Flutter UI.
     *
     * <p>If more than one action is provided, actions are executed in the order provided.
     *
     * @param widgetActions one or more actions that shall be performed. Cannot be {@code null}.
     * @return this interaction for further perform/verification calls.
     */
    public WidgetInteraction perform(@Nonnull final WidgetAction... widgetActions) {
      checkNotNull(widgetActions);
      for (WidgetAction widgetAction : widgetActions) {
        // If any error occurred, an unchecked exception will be thrown that stops execution of
        // following actions.
        performInternal(widgetAction);
      }
      return this;
    }

    /**
     * Evaluates the given widget assertion.
     *
     * @param assertion a widget assertion that shall be made on the matched Flutter widget. Cannot
     *     be {@code null}.
     */
    public WidgetInteraction check(@Nonnull WidgetAssertion assertion) {
      checkNotNull(
          assertion,
          "Assertion cannot be null. You must specify an assertion on the matched Flutter widget.");
      WidgetInfo widgetInfo = performInternal(new WidgetInfoFetcher());
      if (widgetInfo == null) {
        Log.w(TAG, String.format("Widget info that matches %s is null.", widgetMatcher));
        throw new NoMatchingWidgetException(
            String.format("Widget info that matches %s is null.", widgetMatcher));
      }
      FlutterViewAssertion flutterViewAssertion = new FlutterViewAssertion(assertion, widgetInfo);
      onView(flutterViewMatcher).check(flutterViewAssertion);
      return this;
    }

    private <T> T performInternal(FlutterAction<T> flutterAction) {
      checkNotNull(
          flutterAction,
          "The action cannot be null. You must specify an action to perform on the matched"
              + " Flutter widget.");
      FlutterViewAction<T> flutterViewAction =
          new FlutterViewAction(
              widgetMatcher, flutterAction, okHttpClient, idGenerator, taskExecutor);
      onView(flutterViewMatcher).perform(flutterViewAction);
      T result;
      try {
        if (timeout != null && timeout.getQuantity() > 0) {
          result = flutterViewAction.waitUntilCompleted(timeout.getQuantity(), timeout.getUnit());
        } else {
          result = flutterViewAction.waitUntilCompleted();
        }
        return result;
      } catch (ExecutionException e) {
        propagateException(e.getCause());
      } catch (InterruptedException | TimeoutException | RuntimeException e) {
        propagateException(e);
      }
      return null;
    }

    /**
     * Propagates exception through #onView so that it get a chance to be handled by the registered
     * {@code FailureHandler}.
     */
    private void propagateException(Throwable t) {
      onView(flutterViewMatcher).perform(new ExceptionPropagator(t));
    }

    /**
     * An exception wrapper that propagates an exception through {@code #onView}, so that it can be
     * handled by the registered {@code FailureHandler} for the underlying {@code ViewInteraction}.
     */
    static class ExceptionPropagator implements ViewAction {
      private final RuntimeException exception;

      public ExceptionPropagator(RuntimeException exception) {
        this.exception = checkNotNull(exception);
      }

      public ExceptionPropagator(Throwable t) {
        this(new RuntimeException(t));
      }

      @Override
      public String getDescription() {
        return "Propagate: " + exception;
      }

      @Override
      public void perform(UiController uiController, View view) {
        throw exception;
      }

      @SuppressWarnings("unchecked")
      @Override
      public Matcher<View> getConstraints() {
        return any(View.class);
      }
    }
  }
}
