/*
 * 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.v7.widget;

import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
import static android.support.v7.widget.LinearLayoutManager.VERTICAL;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.StateListDrawable;
import android.support.test.filters.LargeTest;
import android.support.v4.view.AccessibilityDelegateCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityRecordCompat;
import android.util.Log;
import android.util.StateSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * Includes tests for {@link LinearLayoutManager}.
 * <p>
 * Since most UI tests are not practical, these tests are focused on internal data representation
 * and stability of LinearLayoutManager in response to different events (state change, scrolling
 * etc) where it is very hard to do manual testing.
 */
@LargeTest
public class LinearLayoutManagerTest extends BaseLinearLayoutManagerTest {

    @Test
    public void topUnfocusableViewsVisibility() throws Throwable {
        // The maximum number of child views that can be visible at any time.
        final int visibleChildCount = 5;
        final int consecutiveFocusablesCount = 2;
        final int consecutiveUnFocusablesCount = 18;
        final TestAdapter adapter = new TestAdapter(
                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
            RecyclerView mAttachedRv;

            @Override
            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
                // Good to have colors for debugging
                StateListDrawable stl = new StateListDrawable();
                stl.addState(new int[]{android.R.attr.state_focused},
                        new ColorDrawable(Color.RED));
                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
                //noinspection deprecation used to support kitkat tests
                testViewHolder.itemView.setBackgroundDrawable(stl);
                return testViewHolder;
            }

            @Override
            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
                mAttachedRv = recyclerView;
            }

            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                if (position < consecutiveFocusablesCount) {
                    holder.itemView.setFocusable(true);
                    holder.itemView.setFocusableInTouchMode(true);
                } else {
                    holder.itemView.setFocusable(false);
                    holder.itemView.setFocusableInTouchMode(false);
                }
                // This height ensures that some portion of #visibleChildCount'th child is
                // off-bounds, creating more interesting test scenario.
                holder.itemView.setMinimumHeight((mAttachedRv.getHeight()
                        + mAttachedRv.getHeight() / (2 * visibleChildCount)) / visibleChildCount);
            }
        };
        setupByConfig(new Config(VERTICAL, false, false).adapter(adapter).reverseLayout(true),
                false);
        waitForFirstLayout();

        // adapter position of the currently focused item.
        int focusIndex = 0;
        View newFocused = mRecyclerView.getChildAt(focusIndex);
        requestFocus(newFocused, true);
        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
                focusIndex);
        assertThat("Child at position " + focusIndex + " should be focused",
                toFocus.itemView.hasFocus(), is(true));

        // adapter position of the item (whether focusable or not) that just becomes fully
        // visible after focusSearch.
        int visibleIndex = 0;
        // The VH of the above adapter position
        RecyclerView.ViewHolder toVisible = null;

        // Navigate up through the focusable and unfocusable chunks. The focusable items should
        // become focused one by one until hitting the last focusable item, at which point,
        // unfocusable items should become visible on the screen until the currently focused item
        // stays on the screen.
        for (int i = 0; i < adapter.getItemCount(); i++) {
            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_UP, true);
            // adapter position of the currently focused item.
            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
                    (visibleIndex + 1));
            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);

            assertThat("Child at position " + focusIndex + " should be focused",
                    toFocus.itemView.hasFocus(), is(true));
            assertTrue("Focused child should be at least partially visible.",
                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
        }
    }

    @Test
    public void bottomUnfocusableViewsVisibility() throws Throwable {
        // The maximum number of child views that can be visible at any time.
        final int visibleChildCount = 5;
        final int consecutiveFocusablesCount = 2;
        final int consecutiveUnFocusablesCount = 18;
        final TestAdapter adapter = new TestAdapter(
                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
            RecyclerView mAttachedRv;

            @Override
            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
                // Good to have colors for debugging
                StateListDrawable stl = new StateListDrawable();
                stl.addState(new int[]{android.R.attr.state_focused},
                        new ColorDrawable(Color.RED));
                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
                //noinspection deprecation used to support kitkat tests
                testViewHolder.itemView.setBackgroundDrawable(stl);
                return testViewHolder;
            }

            @Override
            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
                mAttachedRv = recyclerView;
            }

            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                if (position < consecutiveFocusablesCount) {
                    holder.itemView.setFocusable(true);
                    holder.itemView.setFocusableInTouchMode(true);
                } else {
                    holder.itemView.setFocusable(false);
                    holder.itemView.setFocusableInTouchMode(false);
                }
                // This height ensures that some portion of #visibleChildCount'th child is
                // off-bounds, creating more interesting test scenario.
                holder.itemView.setMinimumHeight((mAttachedRv.getHeight()
                        + mAttachedRv.getHeight() / (2 * visibleChildCount)) / visibleChildCount);
            }
        };
        setupByConfig(new Config(VERTICAL, false, false).adapter(adapter), false);
        waitForFirstLayout();

        // adapter position of the currently focused item.
        int focusIndex = 0;
        View newFocused = mRecyclerView.getChildAt(focusIndex);
        requestFocus(newFocused, true);
        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
                focusIndex);
        assertThat("Child at position " + focusIndex + " should be focused",
                toFocus.itemView.hasFocus(), is(true));

        // adapter position of the item (whether focusable or not) that just becomes fully
        // visible after focusSearch.
        int visibleIndex = 0;
        // The VH of the above adapter position
        RecyclerView.ViewHolder toVisible = null;

        // Navigate down through the focusable and unfocusable chunks. The focusable items should
        // become focused one by one until hitting the last focusable item, at which point,
        // unfocusable items should become visible on the screen until the currently focused item
        // stays on the screen.
        for (int i = 0; i < adapter.getItemCount(); i++) {
            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_DOWN, true);
            // adapter position of the currently focused item.
            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
                    (visibleIndex + 1));
            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);

            assertThat("Child at position " + focusIndex + " should be focused",
                    toFocus.itemView.hasFocus(), is(true));
            assertTrue("Focused child should be at least partially visible.",
                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
        }
    }

    @Test
    public void leftUnfocusableViewsVisibility() throws Throwable {
        // The maximum number of child views that can be visible at any time.
        final int visibleChildCount = 5;
        final int consecutiveFocusablesCount = 2;
        final int consecutiveUnFocusablesCount = 18;
        final TestAdapter adapter = new TestAdapter(
                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
            RecyclerView mAttachedRv;

            @Override
            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
                // Good to have colors for debugging
                StateListDrawable stl = new StateListDrawable();
                stl.addState(new int[]{android.R.attr.state_focused},
                        new ColorDrawable(Color.RED));
                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
                //noinspection deprecation used to support kitkat tests
                testViewHolder.itemView.setBackgroundDrawable(stl);
                return testViewHolder;
            }

            @Override
            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
                mAttachedRv = recyclerView;
            }

            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                if (position < consecutiveFocusablesCount) {
                    holder.itemView.setFocusable(true);
                    holder.itemView.setFocusableInTouchMode(true);
                } else {
                    holder.itemView.setFocusable(false);
                    holder.itemView.setFocusableInTouchMode(false);
                }
                // This width ensures that some portion of #visibleChildCount'th child is
                // off-bounds, creating more interesting test scenario.
                holder.itemView.setMinimumWidth((mAttachedRv.getWidth()
                        + mAttachedRv.getWidth() / (2 * visibleChildCount)) / visibleChildCount);
            }
        };
        setupByConfig(new Config(HORIZONTAL, false, false).adapter(adapter).reverseLayout(true),
                false);
        waitForFirstLayout();

        // adapter position of the currently focused item.
        int focusIndex = 0;
        View newFocused = mRecyclerView.getChildAt(focusIndex);
        requestFocus(newFocused, true);
        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
                focusIndex);
        assertThat("Child at position " + focusIndex + " should be focused",
                toFocus.itemView.hasFocus(), is(true));

        // adapter position of the item (whether focusable or not) that just becomes fully
        // visible after focusSearch.
        int visibleIndex = 0;
        // The VH of the above adapter position
        RecyclerView.ViewHolder toVisible = null;

        // Navigate left through the focusable and unfocusable chunks. The focusable items should
        // become focused one by one until hitting the last focusable item, at which point,
        // unfocusable items should become visible on the screen until the currently focused item
        // stays on the screen.
        for (int i = 0; i < adapter.getItemCount(); i++) {
            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_LEFT, true);
            // adapter position of the currently focused item.
            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
                    (visibleIndex + 1));
            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);

            assertThat("Child at position " + focusIndex + " should be focused",
                    toFocus.itemView.hasFocus(), is(true));
            assertTrue("Focused child should be at least partially visible.",
                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
        }
    }

    @Test
    public void rightUnfocusableViewsVisibility() throws Throwable {
        // The maximum number of child views that can be visible at any time.
        final int visibleChildCount = 5;
        final int consecutiveFocusablesCount = 2;
        final int consecutiveUnFocusablesCount = 18;
        final TestAdapter adapter = new TestAdapter(
                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
            RecyclerView mAttachedRv;

            @Override
            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
                // Good to have colors for debugging
                StateListDrawable stl = new StateListDrawable();
                stl.addState(new int[]{android.R.attr.state_focused},
                        new ColorDrawable(Color.RED));
                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
                //noinspection deprecation used to support kitkat tests
                testViewHolder.itemView.setBackgroundDrawable(stl);
                return testViewHolder;
            }

            @Override
            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
                mAttachedRv = recyclerView;
            }

            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                if (position < consecutiveFocusablesCount) {
                    holder.itemView.setFocusable(true);
                    holder.itemView.setFocusableInTouchMode(true);
                } else {
                    holder.itemView.setFocusable(false);
                    holder.itemView.setFocusableInTouchMode(false);
                }
                // This width ensures that some portion of #visibleChildCount'th child is
                // off-bounds, creating more interesting test scenario.
                holder.itemView.setMinimumWidth((mAttachedRv.getWidth()
                        + mAttachedRv.getWidth() / (2 * visibleChildCount)) / visibleChildCount);
            }
        };
        setupByConfig(new Config(HORIZONTAL, false, false).adapter(adapter), false);
        waitForFirstLayout();

        // adapter position of the currently focused item.
        int focusIndex = 0;
        View newFocused = mRecyclerView.getChildAt(focusIndex);
        requestFocus(newFocused, true);
        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
                focusIndex);
        assertThat("Child at position " + focusIndex + " should be focused",
                toFocus.itemView.hasFocus(), is(true));

        // adapter position of the item (whether focusable or not) that just becomes fully
        // visible after focusSearch.
        int visibleIndex = 0;
        // The VH of the above adapter position
        RecyclerView.ViewHolder toVisible = null;

        // Navigate right through the focusable and unfocusable chunks. The focusable items should
        // become focused one by one until hitting the last focusable item, at which point,
        // unfocusable items should become visible on the screen until the currently focused item
        // stays on the screen.
        for (int i = 0; i < adapter.getItemCount(); i++) {
            focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_RIGHT, true);
            // adapter position of the currently focused item.
            focusIndex = Math.min(consecutiveFocusablesCount - 1, (focusIndex + 1));
            toFocus = mRecyclerView.findViewHolderForAdapterPosition(focusIndex);
            visibleIndex = Math.min(consecutiveFocusablesCount + visibleChildCount - 2,
                    (visibleIndex + 1));
            toVisible = mRecyclerView.findViewHolderForAdapterPosition(visibleIndex);

            assertThat("Child at position " + focusIndex + " should be focused",
                    toFocus.itemView.hasFocus(), is(true));
            assertTrue("Focused child should be at least partially visible.",
                    isViewPartiallyInBound(mRecyclerView, toFocus.itemView));
            assertTrue("Child view at adapter pos " + visibleIndex + " should be fully visible.",
                    isViewFullyInBound(mRecyclerView, toVisible.itemView));
        }
    }

    @Test
    public void unfocusableScrollingWhenFocusCleared() throws Throwable {
        // The maximum number of child views that can be visible at any time.
        final int visibleChildCount = 5;
        final int consecutiveFocusablesCount = 2;
        final int consecutiveUnFocusablesCount = 18;
        final TestAdapter adapter = new TestAdapter(
                consecutiveFocusablesCount + consecutiveUnFocusablesCount) {
            RecyclerView mAttachedRv;

            @Override
            public TestViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
                // Good to have colors for debugging
                StateListDrawable stl = new StateListDrawable();
                stl.addState(new int[]{android.R.attr.state_focused},
                        new ColorDrawable(Color.RED));
                stl.addState(StateSet.WILD_CARD, new ColorDrawable(Color.BLUE));
                //noinspection deprecation used to support kitkat tests
                testViewHolder.itemView.setBackgroundDrawable(stl);
                return testViewHolder;
            }

            @Override
            public void onAttachedToRecyclerView(RecyclerView recyclerView) {
                mAttachedRv = recyclerView;
            }

            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                if (position < consecutiveFocusablesCount) {
                    holder.itemView.setFocusable(true);
                    holder.itemView.setFocusableInTouchMode(true);
                } else {
                    holder.itemView.setFocusable(false);
                    holder.itemView.setFocusableInTouchMode(false);
                }
                // This height ensures that some portion of #visibleChildCount'th child is
                // off-bounds, creating more interesting test scenario.
                holder.itemView.setMinimumHeight((mAttachedRv.getHeight()
                        + mAttachedRv.getHeight() / (2 * visibleChildCount)) / visibleChildCount);
            }
        };
        setupByConfig(new Config(VERTICAL, false, false).adapter(adapter), false);
        waitForFirstLayout();

        // adapter position of the currently focused item.
        int focusIndex = 0;
        View newFocused = mRecyclerView.getChildAt(focusIndex);
        requestFocus(newFocused, true);
        RecyclerView.ViewHolder toFocus = mRecyclerView.findViewHolderForAdapterPosition(
                focusIndex);
        assertThat("Child at position " + focusIndex + " should be focused",
                toFocus.itemView.hasFocus(), is(true));

        final View nextView = focusSearch(mRecyclerView.getFocusedChild(), View.FOCUS_DOWN, true);
        focusIndex++;
        assertThat("Child at position " + focusIndex + " should be focused",
                mRecyclerView.findViewHolderForAdapterPosition(focusIndex).itemView.hasFocus(),
                is(true));
        final CountDownLatch focusLatch = new CountDownLatch(1);
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                nextView.setOnFocusChangeListener(new View.OnFocusChangeListener(){
                    @Override
                    public void onFocusChange(View v, boolean hasFocus) {
                        assertNull("Focus just got cleared and no children should be holding"
                                        + " focus now.", mRecyclerView.getFocusedChild());
                        try {
                            // Calling focusSearch should be a no-op here since even though there
                            // are unfocusable views down to scroll to, none of RV's children hold
                            // focus at this stage.
                            View focusedChild  = focusSearch(v, View.FOCUS_DOWN, true);
                            assertNull("Calling focusSearch should be no-op when no children hold"
                                    + "focus", focusedChild);
                            // No scrolling should have happened, so any unfocusables that were
                            // invisible should still be invisible.
                            RecyclerView.ViewHolder unforcusablePartiallyVisibleChild =
                                    mRecyclerView.findViewHolderForAdapterPosition(
                                            visibleChildCount - 1);
                            assertFalse("Child view at adapter pos " + (visibleChildCount - 1)
                                            + " should not be fully visible.",
                                    isViewFullyInBound(mRecyclerView,
                                            unforcusablePartiallyVisibleChild.itemView));
                        } catch (Throwable t) {
                            postExceptionToInstrumentation(t);
                        }
                    }
                });
                nextView.clearFocus();
                focusLatch.countDown();
            }
        });
        assertTrue(focusLatch.await(2, TimeUnit.SECONDS));
        assertThat("Child at position " + focusIndex + " should no longer be focused",
                mRecyclerView.findViewHolderForAdapterPosition(focusIndex).itemView.hasFocus(),
                is(false));
    }

    @Test
    public void removeAnchorItem() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(VERTICAL).stackFromBottom(false).reverseLayout(
                        false), 100, 0);
    }

    @Test
    public void removeAnchorItemReverse() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(VERTICAL).stackFromBottom(false).reverseLayout(true), 100,
                0);
    }

    @Test
    public void removeAnchorItemStackFromEnd() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(VERTICAL).stackFromBottom(true).reverseLayout(false), 100,
                99);
    }

    @Test
    public void removeAnchorItemStackFromEndAndReverse() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(VERTICAL).stackFromBottom(true).reverseLayout(true), 100,
                99);
    }

    @Test
    public void removeAnchorItemHorizontal() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(HORIZONTAL).stackFromBottom(false).reverseLayout(
                        false), 100, 0);
    }

    @Test
    public void removeAnchorItemReverseHorizontal() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(HORIZONTAL).stackFromBottom(false).reverseLayout(true),
                100, 0);
    }

    @Test
    public void removeAnchorItemStackFromEndHorizontal() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(HORIZONTAL).stackFromBottom(true).reverseLayout(false),
                100, 99);
    }

    @Test
    public void removeAnchorItemStackFromEndAndReverseHorizontal() throws Throwable {
        removeAnchorItemTest(
                new Config().orientation(HORIZONTAL).stackFromBottom(true).reverseLayout(true), 100,
                99);
    }

    /**
     * This tests a regression where predictive animations were not working as expected when the
     * first item is removed and there aren't any more items to add from that direction.
     * First item refers to the default anchor item.
     */
    public void removeAnchorItemTest(final Config config, int adapterSize,
            final int removePos) throws Throwable {
        config.adapter(new TestAdapter(adapterSize) {
            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
                if (!(lp instanceof ViewGroup.MarginLayoutParams)) {
                    lp = new ViewGroup.MarginLayoutParams(0, 0);
                    holder.itemView.setLayoutParams(lp);
                }
                ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) lp;
                final int maxSize;
                if (config.mOrientation == HORIZONTAL) {
                    maxSize = mRecyclerView.getWidth();
                    mlp.height = ViewGroup.MarginLayoutParams.MATCH_PARENT;
                } else {
                    maxSize = mRecyclerView.getHeight();
                    mlp.width = ViewGroup.MarginLayoutParams.MATCH_PARENT;
                }

                final int desiredSize;
                if (position == removePos) {
                    // make it large
                    desiredSize = maxSize / 4;
                } else {
                    // make it small
                    desiredSize = maxSize / 8;
                }
                if (config.mOrientation == HORIZONTAL) {
                    mlp.width = desiredSize;
                } else {
                    mlp.height = desiredSize;
                }
            }
        });
        setupByConfig(config, true);
        final int childCount = mLayoutManager.getChildCount();
        RecyclerView.ViewHolder toBeRemoved = null;
        List<RecyclerView.ViewHolder> toBeMoved = new ArrayList<RecyclerView.ViewHolder>();
        for (int i = 0; i < childCount; i++) {
            View child = mLayoutManager.getChildAt(i);
            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(child);
            if (holder.getAdapterPosition() == removePos) {
                toBeRemoved = holder;
            } else {
                toBeMoved.add(holder);
            }
        }
        assertNotNull("test sanity", toBeRemoved);
        assertEquals("test sanity", childCount - 1, toBeMoved.size());
        LoggingItemAnimator loggingItemAnimator = new LoggingItemAnimator();
        mRecyclerView.setItemAnimator(loggingItemAnimator);
        loggingItemAnimator.reset();
        loggingItemAnimator.expectRunPendingAnimationsCall(1);
        mLayoutManager.expectLayouts(2);
        mTestAdapter.deleteAndNotify(removePos, 1);
        mLayoutManager.waitForLayout(1);
        loggingItemAnimator.waitForPendingAnimationsCall(2);
        assertTrue("removed child should receive remove animation",
                loggingItemAnimator.mRemoveVHs.contains(toBeRemoved));
        for (RecyclerView.ViewHolder vh : toBeMoved) {
            assertTrue("view holder should be in moved list",
                    loggingItemAnimator.mMoveVHs.contains(vh));
        }
        List<RecyclerView.ViewHolder> newHolders = new ArrayList<RecyclerView.ViewHolder>();
        for (int i = 0; i < mLayoutManager.getChildCount(); i++) {
            View child = mLayoutManager.getChildAt(i);
            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(child);
            if (toBeRemoved != holder && !toBeMoved.contains(holder)) {
                newHolders.add(holder);
            }
        }
        assertTrue("some new children should show up for the new space", newHolders.size() > 0);
        assertEquals("no items should receive animate add since they are not new", 0,
                loggingItemAnimator.mAddVHs.size());
        for (RecyclerView.ViewHolder holder : newHolders) {
            assertTrue("new holder should receive a move animation",
                    loggingItemAnimator.mMoveVHs.contains(holder));
        }
        assertTrue("control against adding too many children due to bad layout state preparation."
                        + " initial:" + childCount + ", current:" + mRecyclerView.getChildCount(),
                mRecyclerView.getChildCount() <= childCount + 3 /*1 for removed view, 2 for its size*/);
    }

    @Test
    public void keepFocusOnRelayout() throws Throwable {
        setupByConfig(new Config(VERTICAL, false, false).itemCount(500), true);
        int center = (mLayoutManager.findLastVisibleItemPosition()
                - mLayoutManager.findFirstVisibleItemPosition()) / 2;
        final RecyclerView.ViewHolder vh = mRecyclerView.findViewHolderForLayoutPosition(center);
        final int top = mLayoutManager.mOrientationHelper.getDecoratedStart(vh.itemView);
        requestFocus(vh.itemView, true);
        assertTrue("view should have the focus", vh.itemView.hasFocus());
        // add a bunch of items right before that view, make sure it keeps its position
        mLayoutManager.expectLayouts(2);
        final int childCountToAdd = mRecyclerView.getChildCount() * 2;
        mTestAdapter.addAndNotify(center, childCountToAdd);
        center += childCountToAdd; // offset item
        mLayoutManager.waitForLayout(2);
        mLayoutManager.waitForAnimationsToEnd(20);
        final RecyclerView.ViewHolder postVH = mRecyclerView.findViewHolderForLayoutPosition(center);
        assertNotNull("focused child should stay in layout", postVH);
        assertSame("same view holder should be kept for unchanged child", vh, postVH);
        assertEquals("focused child's screen position should stay unchanged", top,
                mLayoutManager.mOrientationHelper.getDecoratedStart(postVH.itemView));
    }

    @Test
    public void keepFullFocusOnResize() throws Throwable {
        keepFocusOnResizeTest(new Config(VERTICAL, false, false).itemCount(500), true);
    }

    @Test
    public void keepPartialFocusOnResize() throws Throwable {
        keepFocusOnResizeTest(new Config(VERTICAL, false, false).itemCount(500), false);
    }

    @Test
    public void keepReverseFullFocusOnResize() throws Throwable {
        keepFocusOnResizeTest(new Config(VERTICAL, true, false).itemCount(500), true);
    }

    @Test
    public void keepReversePartialFocusOnResize() throws Throwable {
        keepFocusOnResizeTest(new Config(VERTICAL, true, false).itemCount(500), false);
    }

    @Test
    public void keepStackFromEndFullFocusOnResize() throws Throwable {
        keepFocusOnResizeTest(new Config(VERTICAL, false, true).itemCount(500), true);
    }

    @Test
    public void keepStackFromEndPartialFocusOnResize() throws Throwable {
        keepFocusOnResizeTest(new Config(VERTICAL, false, true).itemCount(500), false);
    }

    public void keepFocusOnResizeTest(final Config config, boolean fullyVisible) throws Throwable {
        setupByConfig(config, true);
        final int targetPosition;
        if (config.mStackFromEnd) {
            targetPosition = mLayoutManager.findFirstVisibleItemPosition();
        } else {
            targetPosition = mLayoutManager.findLastVisibleItemPosition();
        }
        final OrientationHelper helper = mLayoutManager.mOrientationHelper;
        final RecyclerView.ViewHolder vh = mRecyclerView
                .findViewHolderForLayoutPosition(targetPosition);

        // scroll enough to offset the child
        int startMargin = helper.getDecoratedStart(vh.itemView) -
                helper.getStartAfterPadding();
        int endMargin = helper.getEndAfterPadding() -
                helper.getDecoratedEnd(vh.itemView);
        Log.d(TAG, "initial start margin " + startMargin + " , end margin:" + endMargin);
        requestFocus(vh.itemView, true);
        assertTrue("view should gain the focus", vh.itemView.hasFocus());
        // scroll enough to offset the child
        startMargin = helper.getDecoratedStart(vh.itemView) -
                helper.getStartAfterPadding();
        endMargin = helper.getEndAfterPadding() -
                helper.getDecoratedEnd(vh.itemView);

        Log.d(TAG, "start margin " + startMargin + " , end margin:" + endMargin);
        assertTrue("View should become fully visible", startMargin >= 0 && endMargin >= 0);

        int expectedOffset = 0;
        boolean offsetAtStart = false;
        if (!fullyVisible) {
            // move it a bit such that it is no more fully visible
            final int childSize = helper
                    .getDecoratedMeasurement(vh.itemView);
            expectedOffset = childSize / 3;
            if (startMargin < endMargin) {
                scrollBy(expectedOffset);
                offsetAtStart = true;
            } else {
                scrollBy(-expectedOffset);
                offsetAtStart = false;
            }
            startMargin = helper.getDecoratedStart(vh.itemView) -
                    helper.getStartAfterPadding();
            endMargin = helper.getEndAfterPadding() -
                    helper.getDecoratedEnd(vh.itemView);
            assertTrue("test sanity, view should not be fully visible", startMargin < 0
                    || endMargin < 0);
        }

        mLayoutManager.expectLayouts(1);
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final ViewGroup.LayoutParams layoutParams = mRecyclerView.getLayoutParams();
                if (config.mOrientation == HORIZONTAL) {
                    layoutParams.width = mRecyclerView.getWidth() / 2;
                } else {
                    layoutParams.height = mRecyclerView.getHeight() / 2;
                }
                mRecyclerView.setLayoutParams(layoutParams);
            }
        });
        Thread.sleep(100);
        // add a bunch of items right before that view, make sure it keeps its position
        mLayoutManager.waitForLayout(2);
        mLayoutManager.waitForAnimationsToEnd(20);
        assertTrue("view should preserve the focus", vh.itemView.hasFocus());
        final RecyclerView.ViewHolder postVH = mRecyclerView
                .findViewHolderForLayoutPosition(targetPosition);
        assertNotNull("focused child should stay in layout", postVH);
        assertSame("same view holder should be kept for unchanged child", vh, postVH);
        View focused = postVH.itemView;

        startMargin = helper.getDecoratedStart(focused) - helper.getStartAfterPadding();
        endMargin = helper.getEndAfterPadding() - helper.getDecoratedEnd(focused);

        assertTrue("focused child should be somewhat visible",
                helper.getDecoratedStart(focused) < helper.getEndAfterPadding()
                        && helper.getDecoratedEnd(focused) > helper.getStartAfterPadding());
        if (fullyVisible) {
            assertTrue("focused child end should stay fully visible",
                    endMargin >= 0);
            assertTrue("focused child start should stay fully visible",
                    startMargin >= 0);
        } else {
            if (offsetAtStart) {
                assertTrue("start should preserve its offset", startMargin < 0);
                assertTrue("end should be visible", endMargin >= 0);
            } else {
                assertTrue("end should preserve its offset", endMargin < 0);
                assertTrue("start should be visible", startMargin >= 0);
            }
        }
    }

    @Test
    public void scrollToPositionWithPredictive() throws Throwable {
        scrollToPositionWithPredictive(0, LinearLayoutManager.INVALID_OFFSET);
        removeRecyclerView();
        scrollToPositionWithPredictive(3, 20);
        removeRecyclerView();
        scrollToPositionWithPredictive(Config.DEFAULT_ITEM_COUNT / 2,
                LinearLayoutManager.INVALID_OFFSET);
        removeRecyclerView();
        scrollToPositionWithPredictive(Config.DEFAULT_ITEM_COUNT / 2, 10);
    }

    @Test
    public void recycleDuringAnimations() throws Throwable {
        final AtomicInteger childCount = new AtomicInteger(0);
        final TestAdapter adapter = new TestAdapter(300) {
            @Override
            public TestViewHolder onCreateViewHolder(ViewGroup parent,
                    int viewType) {
                final int cnt = childCount.incrementAndGet();
                final TestViewHolder testViewHolder = super.onCreateViewHolder(parent, viewType);
                if (DEBUG) {
                    Log.d(TAG, "CHILD_CNT(create):" + cnt + ", " + testViewHolder);
                }
                return testViewHolder;
            }
        };
        setupByConfig(new Config(VERTICAL, false, false).itemCount(300)
                .adapter(adapter), true);

        final RecyclerView.RecycledViewPool pool = new RecyclerView.RecycledViewPool() {
            @Override
            public void putRecycledView(RecyclerView.ViewHolder scrap) {
                super.putRecycledView(scrap);
                int cnt = childCount.decrementAndGet();
                if (DEBUG) {
                    Log.d(TAG, "CHILD_CNT(put):" + cnt + ", " + scrap);
                }
            }

            @Override
            public RecyclerView.ViewHolder getRecycledView(int viewType) {
                final RecyclerView.ViewHolder recycledView = super.getRecycledView(viewType);
                if (recycledView != null) {
                    final int cnt = childCount.incrementAndGet();
                    if (DEBUG) {
                        Log.d(TAG, "CHILD_CNT(get):" + cnt + ", " + recycledView);
                    }
                }
                return recycledView;
            }
        };
        pool.setMaxRecycledViews(mTestAdapter.getItemViewType(0), 500);
        mRecyclerView.setRecycledViewPool(pool);


        // now keep adding children to trigger more children being created etc.
        for (int i = 0; i < 100; i ++) {
            adapter.addAndNotify(15, 1);
            Thread.sleep(15);
        }
        getInstrumentation().waitForIdleSync();
        waitForAnimations(2);
        assertEquals("Children count should add up", childCount.get(),
                mRecyclerView.getChildCount() + mRecyclerView.mRecycler.mCachedViews.size());

        // now trigger lots of add again, followed by a scroll to position
        for (int i = 0; i < 100; i ++) {
            adapter.addAndNotify(5 + (i % 3) * 3, 1);
            Thread.sleep(25);
        }
        smoothScrollToPosition(mLayoutManager.findLastVisibleItemPosition() + 20);
        waitForAnimations(2);
        getInstrumentation().waitForIdleSync();
        assertEquals("Children count should add up", childCount.get(),
                mRecyclerView.getChildCount() + mRecyclerView.mRecycler.mCachedViews.size());
    }


    @Test
    public void dontRecycleChildrenOnDetach() throws Throwable {
        setupByConfig(new Config().recycleChildrenOnDetach(false), true);
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int recyclerSize = mRecyclerView.mRecycler.getRecycledViewPool().size();
                ((ViewGroup)mRecyclerView.getParent()).removeView(mRecyclerView);
                assertEquals("No views are recycled", recyclerSize,
                        mRecyclerView.mRecycler.getRecycledViewPool().size());
            }
        });
    }

    @Test
    public void recycleChildrenOnDetach() throws Throwable {
        setupByConfig(new Config().recycleChildrenOnDetach(true), true);
        final int childCount = mLayoutManager.getChildCount();
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int recyclerSize = mRecyclerView.mRecycler.getRecycledViewPool().size();
                mRecyclerView.mRecycler.getRecycledViewPool().setMaxRecycledViews(
                        mTestAdapter.getItemViewType(0), recyclerSize + childCount);
                ((ViewGroup)mRecyclerView.getParent()).removeView(mRecyclerView);
                assertEquals("All children should be recycled", childCount + recyclerSize,
                        mRecyclerView.mRecycler.getRecycledViewPool().size());
            }
        });
    }

    @Test
    public void scrollAndClear() throws Throwable {
        setupByConfig(new Config(), true);

        assertTrue("Children not laid out", mLayoutManager.collectChildCoordinates().size() > 0);

        mLayoutManager.expectLayouts(1);
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mLayoutManager.scrollToPositionWithOffset(1, 0);
                mTestAdapter.clearOnUIThread();
            }
        });
        mLayoutManager.waitForLayout(2);

        assertEquals("Remaining children", 0, mLayoutManager.collectChildCoordinates().size());
    }


    @Test
    public void accessibilityPositions() throws Throwable {
        setupByConfig(new Config(VERTICAL, false, false), true);
        final AccessibilityDelegateCompat delegateCompat = mRecyclerView
                .getCompatAccessibilityDelegate();
        final AccessibilityEvent event = AccessibilityEvent.obtain();
        mActivityRule.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                delegateCompat.onInitializeAccessibilityEvent(mRecyclerView, event);
            }
        });
        final AccessibilityRecordCompat record = AccessibilityEventCompat
                .asRecord(event);
        assertEquals("result should have first position",
                record.getFromIndex(),
                mLayoutManager.findFirstVisibleItemPosition());
        assertEquals("result should have last position",
                record.getToIndex(),
                mLayoutManager.findLastVisibleItemPosition());
    }
}
