/*
 * Copyright (C) 2008 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.widget.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.database.DataSetObserver;
import android.support.test.annotation.UiThreadTest;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class ArrayAdapterTest {
    private static final int INVALID_ID = -1;
    private static final String STR1 = "string1";
    private static final String STR2 = "string2";
    private static final String STR3 = "string3";

    private ArrayAdapter<String> mArrayAdapter;
    private Context mContext;

    @Rule
    public ActivityTestRule<CtsActivity> mActivityRule =
            new ActivityTestRule<>(CtsActivity.class);

    @Before
    public void setup() {
        mContext = InstrumentationRegistry.getTargetContext();
        mArrayAdapter = new ArrayAdapter<>(mContext, R.layout.simple_dropdown_item_1line);
    }

    @Test
    public void testConstructor() {
        new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line);
        new ArrayAdapter<String>(mContext, INVALID_ID); // invalid resource id

        new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, R.id.text1);
        new ArrayAdapter<String>(mContext, R.layout.simple_dropdown_item_1line, INVALID_ID);

        new ArrayAdapter<>(mContext, R.layout.simple_dropdown_item_1line,
                new String[] {"str1", "str2"});

        new ArrayAdapter<>(mContext, R.layout.simple_dropdown_item_1line, R.id.text1,
                new String[] {"str1", "str2"});

        List<String> list = new ArrayList<>();
        list.add(STR1);
        list.add(STR2);

        new ArrayAdapter<>(mContext, R.layout.simple_dropdown_item_1line, list);

        new ArrayAdapter<>(mContext, R.layout.simple_dropdown_item_1line, R.id.text1, list);
    }

    @Test(expected=NullPointerException.class)
    public void testConstructorWithNullContext() {
        new ArrayAdapter<String>(null, R.layout.simple_dropdown_item_1line);
    }

    @Test
    public void testDataChangeEvent() {
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);

        // enable automatically notifying.
        mArrayAdapter.setNotifyOnChange(true);
        verifyZeroInteractions(mockDataSetObserver);
        mArrayAdapter.add(STR1);
        assertEquals(1, mArrayAdapter.getCount());
        verify(mockDataSetObserver, times(1)).onChanged();
        mArrayAdapter.add(STR2);
        assertEquals(2, mArrayAdapter.getCount());
        verify(mockDataSetObserver, times(2)).onChanged();

        // reset data
        mArrayAdapter.clear();
        // clear notify changed
        verify(mockDataSetObserver, times(3)).onChanged();
        assertEquals(0, mArrayAdapter.getCount());
        // if empty before, clear also notify changed
        mArrayAdapter.clear();
        verify(mockDataSetObserver, times(4)).onChanged();

        reset(mockDataSetObserver);

        // disable auto notify
        mArrayAdapter.setNotifyOnChange(false);

        mArrayAdapter.add(STR3);
        assertEquals(1, mArrayAdapter.getCount());
        verifyZeroInteractions(mockDataSetObserver);

        // manually notify
        mArrayAdapter.notifyDataSetChanged();
        verify(mockDataSetObserver, times(1)).onChanged();
        // no data changed, but force notify
        mArrayAdapter.notifyDataSetChanged();
        verify(mockDataSetObserver, times(2)).onChanged();
        // once called notify, auto notify enabled
        mArrayAdapter.add(STR3);
        verify(mockDataSetObserver, times(3)).onChanged();
    }

    @UiThreadTest
    @Test
    public void testAccessView() {
        final TextView textView = new TextView(mContext);
        textView.setText(STR3);

        assertNotNull(mArrayAdapter.getContext());

        assertEquals(0, mArrayAdapter.getCount());

        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR3);

        assertEquals(3, mArrayAdapter.getCount());

        assertEquals(STR1, ((TextView) mArrayAdapter.getView(0, null, null)).getText());
        assertEquals(STR2, ((TextView) mArrayAdapter.getView(1, null, null)).getText());
        assertEquals(STR3, ((TextView) mArrayAdapter.getDropDownView(2, null, null)).getText());

        assertEquals(STR3, textView.getText());
        assertSame(textView, mArrayAdapter.getView(0, textView, null));
        assertSame(textView, mArrayAdapter.getDropDownView(0, textView, null));
        assertEquals(STR1, textView.getText());
    }

    @UiThreadTest
    @Test(expected=IndexOutOfBoundsException.class)
    public void testGetViewOutOfBoundsLow() {
        final TextView textView = new TextView(mContext);
        mArrayAdapter.getView(-1, textView, null);
    }

    @UiThreadTest
    @Test(expected=IndexOutOfBoundsException.class)
    public void testDropDownGetViewOutOfBoundsLow() {
        final TextView textView = new TextView(mContext);
        mArrayAdapter.getDropDownView(-1, textView, null);
    }

    @UiThreadTest
    @Test(expected=IndexOutOfBoundsException.class)
    public void testGetViewOutOfBoundsHigh() {
        final TextView textView = new TextView(mContext);
        mArrayAdapter.getView(mArrayAdapter.getCount(), textView, null);
    }

    @UiThreadTest
    @Test(expected=IndexOutOfBoundsException.class)
    public void testDropDownGetViewOutOfBoundsHigh() {
        final TextView textView = new TextView(mContext);
        mArrayAdapter.getDropDownView(mArrayAdapter.getCount(), textView, null);
    }

    @Test
    public void testGetFilter() throws Throwable {
        mActivityRule.runOnUiThread(() -> {
            Filter filter = mArrayAdapter.getFilter();

            assertNotNull(mArrayAdapter.getFilter());
            assertSame(filter, mArrayAdapter.getFilter());
        });
    }

    /**
     * Just simple change the resource id from which the drop view inflate from
     * we set a xml that not contain a textview, so exception should throw to lete us know
     * sucessfully change the dropdown xml, but should not affect the normal view by getview
     */
    @UiThreadTest
    @Test
    public void testSetDropDownViewResource() {
        mArrayAdapter.add(STR1);

        mArrayAdapter.getDropDownView(0, null, null);

        mArrayAdapter.setDropDownViewResource(R.layout.tabhost_layout);
        // getview is ok
        mArrayAdapter.getView(0, null, null);

        mArrayAdapter.setDropDownViewResource(INVALID_ID);
    }

    @UiThreadTest
    @Test(expected=IllegalStateException.class)
    public void testSetDropDownViewResourceIllegal() {
        mArrayAdapter.add(STR1);
        mArrayAdapter.setDropDownViewResource(R.layout.tabhost_layout);
        mArrayAdapter.getDropDownView(0, null, null);
    }

    @Test
    public void testAccessDropDownViewTheme() {
        Theme theme = mContext.getResources().newTheme();
        mArrayAdapter.setDropDownViewTheme(theme);
        assertSame(theme, mArrayAdapter.getDropDownViewTheme());
    }

    /**
     * insert the item to the specific position, notify data changed
     * check -1, normal, > count
     */
    @Test
    public void testInsert() {
        mArrayAdapter.setNotifyOnChange(true);
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);

        mArrayAdapter.insert(STR1, 0);
        assertEquals(1, mArrayAdapter.getCount());
        assertEquals(0, mArrayAdapter.getPosition(STR1));
        verify(mockDataSetObserver, times(1)).onChanged();

        mArrayAdapter.insert(STR2, 0);
        assertEquals(2, mArrayAdapter.getCount());
        assertEquals(1, mArrayAdapter.getPosition(STR1));
        assertEquals(0, mArrayAdapter.getPosition(STR2));

        mArrayAdapter.insert(STR3, mArrayAdapter.getCount());
        assertEquals(mArrayAdapter.getCount() - 1, mArrayAdapter.getPosition(STR3));

        mArrayAdapter.insert(null, 0);
        assertEquals(0, mArrayAdapter.getPosition(null));
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testInsertOutOfBoundsLow() {
        mArrayAdapter.insert(STR1, 0);
        mArrayAdapter.insert(STR2, 0);
        mArrayAdapter.insert(null, 0);

        mArrayAdapter.insert(STR1, -1);
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testInsertOutOfBoundsHigh() {
        mArrayAdapter.insert(STR1, 0);
        mArrayAdapter.insert(STR2, 0);
        mArrayAdapter.insert(null, 0);

        mArrayAdapter.insert(STR1, mArrayAdapter.getCount() + 1);
    }

    /**
     * return the given position obj
     * test range: -1, normal, > count
     */
    @Test
    public void testGetItem() {
        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR3);

        assertSame(STR1, mArrayAdapter.getItem(0));
        assertSame(STR2, mArrayAdapter.getItem(1));
        assertSame(STR3, mArrayAdapter.getItem(2));
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testGetItemOutOfBoundsLow() {
        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR3);

        mArrayAdapter.getItem(-1);
    }

    @Test(expected=IndexOutOfBoundsException.class)
    public void testGetItemOutOfBoundsHigh() {
        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR3);

        mArrayAdapter.getItem(mArrayAdapter.getCount());
    }

    /**
     * just return the given position
     */
    @Test
    public void testGetItemId() {
        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR3);

        assertEquals(0, mArrayAdapter.getItemId(0));
        assertEquals(1, mArrayAdapter.getItemId(1));
        assertEquals(2, mArrayAdapter.getItemId(2));

        // test invalid input
        assertEquals(-1, mArrayAdapter.getItemId(-1));
        assertEquals(mArrayAdapter.getCount(), mArrayAdapter.getItemId(mArrayAdapter.getCount()));
    }

    /*
     * return the obj position that in the array, if there are same objs, return the first one
     */
    @Test
    public void testGetPosition() {
        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR1);

        assertEquals(0, mArrayAdapter.getPosition(STR1));
        assertEquals(1, mArrayAdapter.getPosition(STR2));
        // return the first one if same obj exsit
        assertEquals(0, mArrayAdapter.getPosition(STR1));

        assertEquals(-1, mArrayAdapter.getPosition(STR3));

        // test invalid input
        assertEquals(-1, mArrayAdapter.getPosition(null));
    }

    /**
     * Removes the specified object from the array. notify data changed
     * remove first one if duplicated string in the array
     */
    @Test
    public void testRemove() {
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);
        mArrayAdapter.setNotifyOnChange(true);

        // remove the not exist one
        assertEquals(0, mArrayAdapter.getCount());
        verifyZeroInteractions(mockDataSetObserver);
        // remove the item not exist also notify change
        mArrayAdapter.remove(STR1);
        verify(mockDataSetObserver, times(1)).onChanged();

        mArrayAdapter.add(STR1);
        mArrayAdapter.add(STR2);
        mArrayAdapter.add(STR3);
        mArrayAdapter.add(STR2);
        reset(mockDataSetObserver);
        assertEquals(4, mArrayAdapter.getCount());

        mArrayAdapter.remove(STR1);
        assertEquals(3, mArrayAdapter.getCount());
        assertEquals(-1, mArrayAdapter.getPosition(STR1));
        assertEquals(0, mArrayAdapter.getPosition(STR2));
        assertEquals(1, mArrayAdapter.getPosition(STR3));
        verify(mockDataSetObserver, times(1)).onChanged();

        mArrayAdapter.remove(STR2);
        assertEquals(2, mArrayAdapter.getCount());
        // remove the first one if duplicated
        assertEquals(1, mArrayAdapter.getPosition(STR2));
        assertEquals(0, mArrayAdapter.getPosition(STR3));

        mArrayAdapter.remove(STR2);
        assertEquals(1, mArrayAdapter.getCount());
        assertEquals(-1, mArrayAdapter.getPosition(STR2));
        assertEquals(0, mArrayAdapter.getPosition(STR3));
    }

    /*
     * Creates a new ArrayAdapter from external resources. The content of the array is
     * obtained through {@link android.content.res.Resources#getTextArray(int)}.
     */
    @Test
    public void testCreateFromResource() {
        ArrayAdapter.createFromResource(mContext, R.array.string, R.layout.simple_spinner_item);

        ArrayAdapter.createFromResource(mContext, R.array.string, INVALID_ID);
    }

    @Test(expected=NullPointerException.class)
    public void testCreateFromResourceWithNullContext() {
        ArrayAdapter.createFromResource(null, R.array.string, R.layout.simple_spinner_item);
    }

    @Test(expected=Resources.NotFoundException.class)
    public void testCreateFromResourceWithInvalidId() {
        ArrayAdapter.createFromResource(mContext, INVALID_ID, R.layout.simple_spinner_item);
    }

    @Test
    public void testSort() {
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);
        mArrayAdapter.setNotifyOnChange(true);
        verifyZeroInteractions(mockDataSetObserver);

        mArrayAdapter.sort((String o1, String o2) -> 0);
        verify(mockDataSetObserver, times(1)).onChanged();

        mArrayAdapter.sort(null);
        verify(mockDataSetObserver, times(2)).onChanged();
    }

    /**
     * insert multiple items via add, notify data changed
     * check count and content
     */
    @Test
    public void testAdd() {
        mArrayAdapter.setNotifyOnChange(true);
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);

        mArrayAdapter.clear();
        assertEquals(mArrayAdapter.getCount(), 0);

        mArrayAdapter.add("testing");
        mArrayAdapter.add("android");
        assertEquals(mArrayAdapter.getCount(), 2);
        assertEquals(mArrayAdapter.getItem(0), "testing");
        assertEquals(mArrayAdapter.getItem(1), "android");
    }

    /**
     * insert multiple items via addAll, notify data changed
     * check count and content
     */
    @Test
    public void testAddAllCollection() {
        mArrayAdapter.setNotifyOnChange(true);
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);

        List<String> list = new ArrayList<>();
        list.add("");
        list.add("hello");
        list.add("android");
        list.add("!");

        mArrayAdapter.clear();
        assertEquals(mArrayAdapter.getCount(), 0);

        mArrayAdapter.addAll(list);
        assertEquals(mArrayAdapter.getCount(), list.size());

        assertEquals(mArrayAdapter.getItem(0), list.get(0));
        assertEquals(mArrayAdapter.getItem(1), list.get(1));
        assertEquals(mArrayAdapter.getItem(2), list.get(2));
        assertEquals(mArrayAdapter.getItem(3), list.get(3));
    }

    /**
     * insert multiple items via addAll, notify data changed
     * check count and content
     */
    @Test
    public void testAddAllParams() {
        mArrayAdapter.setNotifyOnChange(true);
        final DataSetObserver mockDataSetObserver = mock(DataSetObserver.class);
        mArrayAdapter.registerDataSetObserver(mockDataSetObserver);

        mArrayAdapter.clear();
        assertEquals(mArrayAdapter.getCount(), 0);

        mArrayAdapter.addAll("this", "is", "a", "unit", "test");
        assertEquals(mArrayAdapter.getCount(), 5);
        assertEquals(mArrayAdapter.getItem(0), "this");
        assertEquals(mArrayAdapter.getItem(1), "is");
        assertEquals(mArrayAdapter.getItem(2), "a");
        assertEquals(mArrayAdapter.getItem(3), "unit");
        assertEquals(mArrayAdapter.getItem(4), "test");
    }
}
