/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.support.test.espresso.action;

import static com.google.common.base.Preconditions.checkNotNull;

import android.support.test.espresso.UiController;
import android.support.test.espresso.action.MotionEvents.DownResultHolder;

import android.os.Build;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Executes different click types to given position.
 */
public enum Tap implements Tapper {
  SINGLE {
  @Override
    public Tapper.Status sendTap(UiController uiController, float[] coordinates,
        float[] precision) {
      Tapper.Status stat = sendSingleTap(uiController, coordinates, precision);
      if (Tapper.Status.SUCCESS == stat) {
        // Wait until the touch event was processed by the main thread.
        long singlePressTimeout = (long) (ViewConfiguration.getTapTimeout() * 1.5f);
        uiController.loopMainThreadForAtLeast(singlePressTimeout);
      }
      return stat;
    }
  },
  LONG {
  @Override
    public Tapper.Status sendTap(UiController uiController, float[] coordinates,
        float[] precision) {
      checkNotNull(uiController);
      checkNotNull(coordinates);
      checkNotNull(precision);

      MotionEvent downEvent = MotionEvents.sendDown(uiController, coordinates, precision).down;
      try {
        // Duration before a press turns into a long press.
        // Factor 1.5 is needed, otherwise a long press is not safely detected.
        // See android.test.TouchUtils longClickView
        long longPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
        uiController.loopMainThreadForAtLeast(longPressTimeout);

        if (!MotionEvents.sendUp(uiController, downEvent)) {
          MotionEvents.sendCancel(uiController, downEvent);
          return Tapper.Status.FAILURE;
        }
      } finally {
        downEvent.recycle();
        downEvent = null;
      }
      return Tapper.Status.SUCCESS;
    }
  },
  DOUBLE {
  @Override
    public Tapper.Status sendTap(UiController uiController, float[] coordinates,
        float[] precision) {
      checkNotNull(uiController);
      checkNotNull(coordinates);
      checkNotNull(precision);
      Tapper.Status stat = sendSingleTap(uiController, coordinates, precision);
      if (stat == Tapper.Status.FAILURE) {
        return Tapper.Status.FAILURE;
      }


      if (0 < DOUBLE_TAP_MIN_TIMEOUT) {
        uiController.loopMainThreadForAtLeast(DOUBLE_TAP_MIN_TIMEOUT);
      }

      Tapper.Status secondStat = sendSingleTap(uiController, coordinates, precision);

      if (secondStat == Tapper.Status.FAILURE) {
        return Tapper.Status.FAILURE;
      }


      if (secondStat == Tapper.Status.WARNING || stat == Tapper.Status.WARNING) {
        return Tapper.Status.WARNING;
      } else {
        return Tapper.Status.SUCCESS;
      }
    }
  };

  private static final String TAG = Tap.class.getSimpleName();
  private static final int DOUBLE_TAP_MIN_TIMEOUT;
  static {
    int timeVal = 0;
    if (Build.VERSION.SDK_INT > 18) {
      try {
        Method getDoubleTapMinTimeMethod = ViewConfiguration.class.getDeclaredMethod(
          "getDoubleTapMinTime");
        timeVal = (Integer) getDoubleTapMinTimeMethod.invoke(null);
      } catch (NoSuchMethodException nsme) {
        Log.w(TAG, "Expected to find getDoubleTapMinTime", nsme);
      } catch (InvocationTargetException ite) {
        Log.w(TAG, "Unable to query double tap min time!", ite);
      } catch (IllegalAccessException iae) {
        Log.w(TAG, "Unable to query double tap min time!", iae);
      }
    }
    DOUBLE_TAP_MIN_TIMEOUT = timeVal;
  }

  private static Tapper.Status sendSingleTap(UiController uiController,
      float[] coordinates, float[] precision) {
    checkNotNull(uiController);
    checkNotNull(coordinates);
    checkNotNull(precision);
    DownResultHolder res = MotionEvents.sendDown(uiController, coordinates, precision);
    try {
      if (!MotionEvents.sendUp(uiController, res.down)) {
        Log.d(TAG, "Injection of up event as part of the click failed. Send cancel event.");
        MotionEvents.sendCancel(uiController, res.down);
        return Tapper.Status.FAILURE;
      }
    } finally {
      res.down.recycle();
    }
    return res.longPress ? Tapper.Status.WARNING : Tapper.Status.SUCCESS;
  }

}
