// Copyright 2018 The Feed Authors.
//
// 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 com.google.android.libraries.feed.piet;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.view.Gravity;
import android.view.View;
import com.google.android.libraries.feed.piet.host.ActionHandler;
import com.google.android.libraries.feed.piet.host.ActionHandler.ActionType;
import com.google.android.libraries.feed.testing.shadows.ExtendedShadowView;
import com.google.search.now.ui.piet.ActionsProto.Action;
import com.google.search.now.ui.piet.ActionsProto.Actions;
import com.google.search.now.ui.piet.ActionsProto.VisibilityAction;
import com.google.search.now.ui.piet.PietProto.Frame;
import com.google.search.now.ui.piet.StylesProto.GravityHorizontal;
import com.google.search.now.ui.piet.StylesProto.GravityVertical;
import java.util.HashSet;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;

/** Tests of the {@link ViewUtils}. */
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ExtendedShadowView.class})
public class ViewUtilsTest {
  private final Context context = Robolectric.buildActivity(Activity.class).get();

  private static final Frame DEFAULT_FRAME = Frame.newBuilder().setTag("Frame").build();
  private static final Action DEFAULT_ACTION = Action.getDefaultInstance();
  private static final Actions DEFAULT_ACTIONS =
      Actions.newBuilder().setOnClickAction(DEFAULT_ACTION).build();
  private static final Actions LONG_CLICK_ACTIONS =
      Actions.newBuilder().setOnLongClickAction(DEFAULT_ACTION).build();
  private static final Action PARTIAL_VIEW_ACTION = Action.newBuilder().build();
  private static final Action FULL_VIEW_ACTION = Action.newBuilder().build();
  private static final Actions VIEW_ACTIONS =
      Actions.newBuilder()
          .addOnViewActions(
              VisibilityAction.newBuilder()
                  .setProportionVisible(0.01f)
                  .setAction(PARTIAL_VIEW_ACTION))
          .addOnViewActions(
              VisibilityAction.newBuilder().setProportionVisible(1.00f).setAction(FULL_VIEW_ACTION))
          .build();

  // Triggers when more than 1% of the view is visible
  private static final VisibilityAction VIEW_ACTION =
      VisibilityAction.newBuilder()
          .setProportionVisible(0.01f)
          .setAction(Action.newBuilder().build())
          .build();
  // Triggers when more than 1% of the view is hidden
  private static final VisibilityAction HIDE_ACTION =
      VisibilityAction.newBuilder()
          .setProportionVisible(0.99f)
          .setAction(Action.newBuilder().build())
          .build();
  private static final Actions VIEW_AND_HIDE_ACTIONS =
      Actions.newBuilder().addOnViewActions(VIEW_ACTION).addOnHideActions(HIDE_ACTION).build();

  @Mock private ActionHandler mockActionHandler;
  @Mock private FrameContext mockFrameContext;
  @Mock private View.OnClickListener mockListener;
  @Mock private View.OnLongClickListener mockLongClickListener;

  private final View view = new View(context);
  private final View viewport = new View(context);

  private final ExtendedShadowView viewShadow = Shadow.extract(view);
  private final ExtendedShadowView viewportShadow = Shadow.extract(viewport);

  private final Set<VisibilityAction> activeActions = new HashSet<>();

  @Before
  public void setUp() {
    initMocks(this);
    when(mockFrameContext.getFrame()).thenReturn(DEFAULT_FRAME);
    when(mockFrameContext.getActionHandler()).thenReturn(mockActionHandler);
  }

  @Test
  public void testGravity() {
    assertThat(
            ViewUtils.pietGravityToGravity(
                GravityHorizontal.GRAVITY_CENTER, GravityVertical.GRAVITY_BOTTOM))
        .isEqualTo(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
    assertThat(
            ViewUtils.pietGravityToGravity(
                GravityHorizontal.GRAVITY_END, GravityVertical.GRAVITY_VERTICAL_UNSPECIFIED))
        .isEqualTo(Gravity.END);
    assertThat(
            ViewUtils.pietGravityToGravity(
                GravityHorizontal.GRAVITY_HORIZONTAL_UNSPECIFIED, GravityVertical.GRAVITY_MIDDLE))
        .isEqualTo(Gravity.START | Gravity.CENTER_VERTICAL);
  }

  @Test
  public void testHorizontalGravity() {
    assertThat(ViewUtils.gravityHorizontalToGravity(GravityHorizontal.GRAVITY_START))
        .isEqualTo(Gravity.START);
    assertThat(ViewUtils.gravityHorizontalToGravity(GravityHorizontal.GRAVITY_CENTER))
        .isEqualTo(Gravity.CENTER_HORIZONTAL);
    assertThat(ViewUtils.gravityHorizontalToGravity(GravityHorizontal.GRAVITY_END))
        .isEqualTo(Gravity.END);
    assertThat(
            ViewUtils.gravityHorizontalToGravity(GravityHorizontal.GRAVITY_HORIZONTAL_UNSPECIFIED))
        .isEqualTo(Gravity.START);
  }

  @Test
  public void testVerticalGravity() {
    assertThat(ViewUtils.gravityVerticalToGravity(GravityVertical.GRAVITY_TOP))
        .isEqualTo(Gravity.TOP);
    assertThat(ViewUtils.gravityVerticalToGravity(GravityVertical.GRAVITY_MIDDLE))
        .isEqualTo(Gravity.CENTER_VERTICAL);
    assertThat(ViewUtils.gravityVerticalToGravity(GravityVertical.GRAVITY_BOTTOM))
        .isEqualTo(Gravity.BOTTOM);
    assertThat(ViewUtils.gravityVerticalToGravity(GravityVertical.GRAVITY_VERTICAL_UNSPECIFIED))
        .isEqualTo(Gravity.NO_GRAVITY);
  }

  @Test
  public void testSetOnClickActions_success() {
    ViewUtils.setOnClickActions(DEFAULT_ACTIONS, view, mockFrameContext);

    assertThat(view.hasOnClickListeners()).isTrue();

    view.callOnClick();
    verify(mockActionHandler)
        .handleAction(DEFAULT_ACTION, ActionType.CLICK, DEFAULT_FRAME, view, null);
    assertThat(view.getForeground()).isInstanceOf(RippleDrawable.class);
  }

  @Test
  public void testSetOnLongClickActions_success() {
    ViewUtils.setOnClickActions(LONG_CLICK_ACTIONS, view, mockFrameContext);

    view.performLongClick();
    verify(mockActionHandler)
        .handleAction(DEFAULT_ACTION, ActionType.LONG_CLICK, DEFAULT_FRAME, view, null);
    assertThat(view.getForeground()).isInstanceOf(RippleDrawable.class);
  }

  @Test
  public void testSetOnClickActions_noOnClickActionsDefinedClearsActions() {
    view.setOnClickListener(mockListener);
    assertThat(view.hasOnClickListeners()).isTrue();

    ViewUtils.setOnClickActions(Actions.getDefaultInstance(), view, mockFrameContext);

    assertViewNotClickable();
    assertThat(view.getForeground()).isNull();
  }

  @Test
  public void testSetOnClickActions_noOnLongClickActionsDefinedClearsActions() {
    view.setOnLongClickListener(mockLongClickListener);
    assertThat(view.isLongClickable()).isTrue();

    ViewUtils.setOnClickActions(Actions.getDefaultInstance(), view, mockFrameContext);

    assertThat(view.isLongClickable()).isFalse();
    assertThat(view.getForeground()).isNull();
  }

  @Test
  public void testClearOnClickActions_success() {
    view.setOnClickListener(mockListener);
    assertThat(view.hasOnClickListeners()).isTrue();

    ViewUtils.clearOnClickActions(view);

    assertViewNotClickable();
  }

  @Test
  public void testClearOnLongClickActions_success() {
    view.setOnLongClickListener(mockLongClickListener);
    assertThat(view.isLongClickable()).isTrue();

    ViewUtils.clearOnLongClickActions(view);

    assertThat(view.isLongClickable()).isFalse();
  }

  @Test
  public void testSetAndClearClickActions() {
    ViewUtils.setOnClickActions(
        Actions.newBuilder()
            .setOnClickAction(DEFAULT_ACTION)
            .setOnLongClickAction(DEFAULT_ACTION)
            .build(),
        view,
        mockFrameContext);
    ViewUtils.setOnClickActions(Actions.getDefaultInstance(), view, mockFrameContext);

    assertViewNotClickable();
    assertThat(view.isLongClickable()).isFalse();
    assertThat(view.getForeground()).isNull();
  }

  @Test
  public void testViewActions_notVisible() {
    setupFullViewScenario();
    view.setVisibility(View.INVISIBLE);
    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_notAttached() {
    setupFullViewScenario();
    viewShadow.setAttachedToWindow(false);
    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_notIntersecting() {
    setupFullViewScenario();
    viewportShadow.setLocationOnScreen(0, 0);
    viewportShadow.setHeight(100);
    viewportShadow.setWidth(100);
    viewShadow.setLocationOnScreen(1000, 1000);
    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_intersectionTriggersPartialView() {
    setupPartialViewScenario();
    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verify(mockActionHandler)
        .handleAction(
            same(PARTIAL_VIEW_ACTION),
            eq(ActionType.VIEW),
            same(DEFAULT_FRAME),
            same(view),
            eq(null));
  }

  @Test
  public void testViewActions_fullyOverlappingTriggersFullViewAndPartialView() {
    setupFullViewScenario();
    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verify(mockActionHandler)
        .handleAction(
            same(FULL_VIEW_ACTION), eq(ActionType.VIEW), same(DEFAULT_FRAME), same(view), eq(null));
    verify(mockActionHandler)
        .handleAction(
            same(PARTIAL_VIEW_ACTION),
            eq(ActionType.VIEW),
            same(DEFAULT_FRAME),
            same(view),
            eq(null));
  }

  @Test
  public void testViewActions_fullOverlapTriggersActions() {
    setupFullViewScenario();
    viewShadow.setLocationOnScreen(0, 0);
    viewShadow.setWidth(100);
    viewShadow.setHeight(100);
    viewportShadow.setLocationOnScreen(0, 0);
    viewportShadow.setWidth(100);
    viewportShadow.setHeight(100);

    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verify(mockActionHandler)
        .handleAction(
            same(FULL_VIEW_ACTION), eq(ActionType.VIEW), same(DEFAULT_FRAME), same(view), eq(null));
    verify(mockActionHandler)
        .handleAction(
            same(PARTIAL_VIEW_ACTION),
            eq(ActionType.VIEW),
            same(DEFAULT_FRAME),
            same(view),
            eq(null));
  }

  @Test
  public void testViewActions_noPartialViewAction() {
    setupFullViewScenario();
    ViewUtils.maybeTriggerViewActions(
        view,
        viewport,
        Actions.newBuilder()
            .addOnViewActions(
                VisibilityAction.newBuilder()
                    .setProportionVisible(1.00f)
                    .setAction(FULL_VIEW_ACTION))
            .build(),
        mockActionHandler,
        DEFAULT_FRAME,
        activeActions);
    verify(mockActionHandler)
        .handleAction(
            same(FULL_VIEW_ACTION), eq(ActionType.VIEW), same(DEFAULT_FRAME), same(view), eq(null));
  }

  @Test
  public void testViewActions_noFullViewAction() {
    setupFullViewScenario();
    ViewUtils.maybeTriggerViewActions(
        view,
        viewport,
        Actions.newBuilder()
            .addOnViewActions(
                VisibilityAction.newBuilder()
                    .setProportionVisible(0.01f)
                    .setAction(PARTIAL_VIEW_ACTION))
            .build(),
        mockActionHandler,
        DEFAULT_FRAME,
        activeActions);
    verify(mockActionHandler)
        .handleAction(
            same(PARTIAL_VIEW_ACTION),
            eq(ActionType.VIEW),
            same(DEFAULT_FRAME),
            same(view),
            eq(null));
  }

  @Test
  public void testViewActions_hideActionsNotTriggered() {
    setupFullViewScenario();
    ViewUtils.maybeTriggerViewActions(
        view,
        viewport,
        Actions.newBuilder()
            .addOnHideActions(
                VisibilityAction.newBuilder()
                    .setProportionVisible(0.01f)
                    .setAction(PARTIAL_VIEW_ACTION))
            .build(),
        mockActionHandler,
        DEFAULT_FRAME,
        activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_hideActionsTriggered() {
    setupPartialViewScenario();
    ViewUtils.maybeTriggerViewActions(
        view,
        viewport,
        Actions.newBuilder()
            .addOnHideActions(
                VisibilityAction.newBuilder()
                    .setProportionVisible(0.90f)
                    .setAction(PARTIAL_VIEW_ACTION))
            .build(),
        mockActionHandler,
        DEFAULT_FRAME,
        activeActions);
    verify(mockActionHandler)
        .handleAction(
            same(PARTIAL_VIEW_ACTION),
            eq(ActionType.VIEW),
            same(DEFAULT_FRAME),
            same(view),
            eq(null));
  }

  @Test
  public void testViewActions_activeActionsPreventsTriggering_notVisible() {
    activeActions.add(VIEW_ACTION);
    activeActions.add(HIDE_ACTION);

    setupFullViewScenario();
    viewShadow.setLocationOnScreen(1000, 1000);
    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_activeActionsPreventsTriggering_partiallyVisible() {
    setupPartialViewScenario();
    activeActions.add(VIEW_ACTION);
    activeActions.add(HIDE_ACTION);

    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_activeActionsPreventsTriggering_fullyVisible() {
    setupFullViewScenario();
    activeActions.add(VIEW_ACTION);
    activeActions.add(HIDE_ACTION);

    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verifyZeroInteractions(mockActionHandler);
  }

  @Test
  public void testViewActions_notAttachedUnsetsActiveActions() {
    setupFullViewScenario();
    viewShadow.setAttachedToWindow(false);
    activeActions.add(VIEW_ACTION);

    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    assertThat(activeActions).containsExactly(HIDE_ACTION);
  }

  @Test
  public void testViewActions_notVisibleUnsetsActiveActions() {
    setupFullViewScenario();
    view.setVisibility(View.INVISIBLE);
    activeActions.add(VIEW_ACTION);

    ViewUtils.maybeTriggerViewActions(
        view, viewport, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    assertThat(activeActions).containsExactly(HIDE_ACTION);
  }

  @Test
  public void testHideActions() {
    ViewUtils.triggerHideActions(
        view, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    assertThat(activeActions).containsExactly(HIDE_ACTION);
    verify(mockActionHandler)
        .handleAction(HIDE_ACTION.getAction(), ActionType.VIEW, DEFAULT_FRAME, view, null);
  }

  @Test
  public void testHideActions_deduplicates() {
    ViewUtils.triggerHideActions(
        view, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verify(mockActionHandler)
        .handleAction(HIDE_ACTION.getAction(), ActionType.VIEW, DEFAULT_FRAME, view, null);

    assertThat(activeActions).containsExactly(HIDE_ACTION);

    // Hide action is not triggered again.
    ViewUtils.triggerHideActions(
        view, VIEW_AND_HIDE_ACTIONS, mockActionHandler, DEFAULT_FRAME, activeActions);
    verify(mockActionHandler, times(1))
        .handleAction(HIDE_ACTION.getAction(), ActionType.VIEW, DEFAULT_FRAME, view, null);
  }

  @Test
  public void testApplyOverlayColor_setsColorFilter() {
    int overlayColor1 = 0xFFEEDDCC;
    int overlayColor2 = 0xCCDDEEFF;
    Drawable original = new BitmapDrawable(Bitmap.createBitmap(12, 34, Bitmap.Config.ARGB_8888));

    Drawable result1 = ViewUtils.applyOverlayColor(original, overlayColor1);
    Drawable result2 = ViewUtils.applyOverlayColor(original, overlayColor2);

    assertThat(result1).isNotSameInstanceAs(original);
    assertThat(result1.getColorFilter())
        .isEqualTo(new PorterDuffColorFilter(overlayColor1, Mode.SRC_IN));

    assertThat(result2).isNotSameInstanceAs(original);
    assertThat(result2.getColorFilter())
        .isEqualTo(new PorterDuffColorFilter(overlayColor2, Mode.SRC_IN));
  }

  @Test
  public void testApplyOverlayColor_nullIsNoOp() {
    Drawable original = new BitmapDrawable(Bitmap.createBitmap(12, 34, Bitmap.Config.ARGB_8888));

    Drawable result1 = ViewUtils.applyOverlayColor(original, null);

    assertThat(result1).isSameInstanceAs(original);
    assertThat(result1.getColorFilter()).isNull();
  }

  /** Sets up view and viewport so that view should be fully visible. */
  private void setupFullViewScenario() {
    view.setVisibility(View.VISIBLE);
    viewShadow.setAttachedToWindow(true);
    viewShadow.setLocationOnScreen(10, 10);
    viewShadow.setWidth(10);
    viewShadow.setHeight(10);

    viewport.setVisibility(View.VISIBLE);
    viewportShadow.setAttachedToWindow(true);
    viewportShadow.setLocationOnScreen(0, 0);
    viewportShadow.setWidth(100);
    viewportShadow.setHeight(100);

    activeActions.clear();
  }

  private void setupPartialViewScenario() {
    setupFullViewScenario();
    viewShadow.setHeight(1000);
  }

  private void assertViewNotClickable() {
    assertThat(view.hasOnClickListeners()).isFalse();
    assertThat(view.isClickable()).isFalse();
  }
}
