/*
 * 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 com.android.internal.R;

import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import dalvik.annotation.ToBeFixed;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.test.InstrumentationTestCase;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.TwoLineListItem;
import android.widget.SimpleAdapter.ViewBinder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Test {@link SimpleAdapter}.
 */
@TestTargetClass(SimpleAdapter.class)
public class SimpleAdapterTest extends InstrumentationTestCase {
    private static final int DEFAULT_ROW_COUNT = 20;

    private static final int DEFAULT_COLUMN_COUNT = 2;

    private static final int[] VIEWS_TO = new int[] { R.id.text1 };

    private static final String[] COLUMNS_FROM = new String[] { "column1" };

    /**
     * The original cursor and its content will be set to:
     * <TABLE>
     * <TR>
     * <TH>Column0</TH>
     * <TH>Column1</TH>
     * </TR>
     * <TR>
     * <TD>00</TD>
     * <TD>01</TD>
     * </TR>
     * <TR>
     * <TD>10</TD>
     * <TD>11</TD>
     * </TR>
     * <TR>
     * <TD>...</TD>
     * <TD>...</TD>
     * </TR>
     * <TR>
     * <TD>190</TD>
     * <TD>191</TD>
     * </TR>
     * </TABLE>
     * It has 2 columns and 20 rows. The default layout for item
     * is R.layout.simple_list_item_1
     */
    private SimpleAdapter mSimpleAdapter;

    private Context mContext;

    private LinearLayout mAdapterHost;

    private LayoutInflater mInflater;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mContext = getInstrumentation().getTargetContext();
        mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mAdapterHost = (LinearLayout) mInflater.inflate(
                com.android.cts.stub.R.layout.cursoradapter_host, null);

        // new the SimpleAdapter instance
        mSimpleAdapter = new SimpleAdapter(mContext,
                createTestList(DEFAULT_COLUMN_COUNT, DEFAULT_ROW_COUNT),
                R.layout.simple_list_item_1, COLUMNS_FROM, VIEWS_TO);
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test constructor",
        method = "SimpleAdapter",
        args = {android.content.Context.class, java.util.List.class, int.class,
                java.lang.String[].class, int[].class}
    )
    public void testConstructor() {
        new SimpleAdapter(mContext, createTestList(DEFAULT_COLUMN_COUNT, DEFAULT_ROW_COUNT),
                R.layout.simple_list_item_1, COLUMNS_FROM, VIEWS_TO);
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#getCount()}",
        method = "getCount",
        args = {}
    )
    public void testGetCount() {
        mSimpleAdapter = new SimpleAdapter(mContext,
                createTestList(DEFAULT_COLUMN_COUNT, DEFAULT_ROW_COUNT),
                R.layout.simple_list_item_1, COLUMNS_FROM, VIEWS_TO);
        assertEquals(20, mSimpleAdapter.getCount());

        mSimpleAdapter = new SimpleAdapter(mContext, createTestList(DEFAULT_COLUMN_COUNT, 10),
                R.layout.simple_list_item_1, COLUMNS_FROM, VIEWS_TO);
        assertEquals(10, mSimpleAdapter.getCount());
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#getItem(int)}",
        method = "getItem",
        args = {int.class}
    )
    @ToBeFixed(bug = "1417734", explanation = "should add @throws clause into javadoc of "
            + "SimpleAdapter#getItem(int) if the param position is out of index")
    public void testGetItem() {
        assertEquals("01", ((Map<?, ?>) mSimpleAdapter.getItem(0)).get("column1"));
        assertEquals("191", ((Map<?, ?>) mSimpleAdapter.getItem(19)).get("column1"));

        try {
            mSimpleAdapter.getItem(-1);
            fail("Should throw IndexOutOfBoundsException if index is negative");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            mSimpleAdapter.getItem(20);
            fail("Should throw IndexOutOfBoundsException if index is beyond the list's size");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#getItemId(int)}",
        method = "getItemId",
        args = {int.class}
    )
    @ToBeFixed(explanation = "SimpleAdapter#getItemId(int) should check whether "
            + "the param position is out of index")
    public void testGetItemId() {
        assertEquals(0, mSimpleAdapter.getItemId(0));

        assertEquals(19, mSimpleAdapter.getItemId(19));

        // are the following behaviors correct?
        assertEquals(-1, mSimpleAdapter.getItemId(-1));

        assertEquals(20, mSimpleAdapter.getItemId(20));
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#getView(int, View, ViewGroup)}",
        method = "getView",
        args = {int.class, android.view.View.class, android.view.ViewGroup.class}
    )
    @ToBeFixed(bug = "1417734", explanation = "should add @throws clause into javadoc of "
            + "SimpleAdapter#getView(int, View, ViewGroup) if the param position is out of index")
    public void testGetView() {
        // use the layout passed in to constructor
        View result = mSimpleAdapter.getView(0, null, mAdapterHost);
        assertTrue(result instanceof TextView);
        assertEquals("01", ((TextView) result).getText().toString());

        result = mSimpleAdapter.getView(19, null, mAdapterHost);
        assertTrue(result instanceof TextView);
        assertEquals("191", ((TextView) result).getText().toString());

        // use the previous result as the convert view
        // the param ViewGroup is never read
        TextView convertView = (TextView) result;
        result = mSimpleAdapter.getView(0, convertView, mAdapterHost);
        assertEquals("01", ((TextView) result).getText().toString());
        assertSame(convertView, result);

        // parent can be null
        result = mSimpleAdapter.getView(10, convertView, null);
        assertEquals("101", ((TextView) result).getText().toString());

        // the binder takes care of binding, the param ViewGroup is never readed
        MockViewBinder binder = new MockViewBinder(true);
        mSimpleAdapter.setViewBinder(binder);
        binder.reset();
        mSimpleAdapter.getView(0, null, mAdapterHost);
        assertTrue(binder.hasCalledSetViewValue());

        // binder try binding but fail
        binder = new MockViewBinder(false);
        mSimpleAdapter.setViewBinder(binder);
        binder.reset();
        result = mSimpleAdapter.getView(0, null, mAdapterHost);
        assertTrue(binder.hasCalledSetViewValue());
        assertEquals("01", ((TextView) result).getText().toString());

        try {
            mSimpleAdapter.getView(-1, convertView, null);
            fail("Should throw IndexOutOfBoundsException if index is negative");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            mSimpleAdapter.getView(20, convertView, null);
            fail("Should throw IndexOutOfBoundsException if index is beyond the list's size");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#setDropDownViewResource(int)}",
        method = "setDropDownViewResource",
        args = {int.class}
    )
    public void testSetDropDownViewResource() {
        mSimpleAdapter.setDropDownViewResource(R.layout.simple_list_item_2);
        View result = mSimpleAdapter.getDropDownView(0, null, mAdapterHost);
        assertTrue(result instanceof TwoLineListItem);
        assertEquals("01", ((TextView) result.findViewById(R.id.text1)).getText().toString());

        result = mSimpleAdapter.getDropDownView(19, null, mAdapterHost);
        assertTrue(result instanceof TwoLineListItem);
        assertEquals("191", ((TextView) result.findViewById(R.id.text1)).getText().toString());

        mSimpleAdapter.setDropDownViewResource(R.layout.simple_list_item_1);
        result = mSimpleAdapter.getDropDownView(0, null, mAdapterHost);
        assertTrue(result instanceof TextView);
        assertEquals("01", ((TextView) result).getText().toString());

        result = mSimpleAdapter.getDropDownView(19, null, mAdapterHost);
        assertTrue(result instanceof TextView);
        assertEquals("191", ((TextView) result).getText().toString());
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#getDropDownView(int, View, ViewGroup)}",
        method = "getDropDownView",
        args = {int.class, android.view.View.class, android.view.ViewGroup.class}
    )
    @ToBeFixed(bug = "1417734", explanation = "should add @throws clause into j"
            + "avadoc of SimpleAdapter#getDropDownView(int, View, ViewGroup) if "
            + "the param position is out of index")
    public void testGetDropDownView() {
        View result = mSimpleAdapter.getDropDownView(0, null, mAdapterHost);
        assertTrue(result instanceof TextView);
        assertEquals("01", ((TextView) result).getText().toString());

        result = mSimpleAdapter.getDropDownView(19, null, mAdapterHost);
        assertTrue(result instanceof TextView);
        assertEquals("191", ((TextView) result).getText().toString());

        // use the previous result as the convert view
        TextView convertView = (TextView) result;
        // the param ViewGroup is never read
        result = mSimpleAdapter.getDropDownView(0, convertView, mAdapterHost);
        assertEquals("01", convertView.getText().toString());
        assertSame(convertView, result);

        // The parent can be null
        result = mSimpleAdapter.getDropDownView(10, convertView, null);
        assertEquals("101", ((TextView) result).getText().toString());

        // the binder takes care of binding, the param ViewGroup is never readed
        MockViewBinder binder = new MockViewBinder(true);
        mSimpleAdapter.setViewBinder(binder);
        binder.reset();
        mSimpleAdapter.getDropDownView(19, null, mAdapterHost);
        assertTrue(binder.hasCalledSetViewValue());

        // binder try binding but fail
        binder = new MockViewBinder(false);
        mSimpleAdapter.setViewBinder(binder);
        binder.reset();
        result = mSimpleAdapter.getDropDownView(19, null, mAdapterHost);
        assertTrue(binder.hasCalledSetViewValue());
        assertEquals("191", ((TextView)result).getText().toString());

        try {
            mSimpleAdapter.getDropDownView(-1, convertView, null);
            fail("Should throw IndexOutOfBoundsException if index is negative");
        } catch (IndexOutOfBoundsException e) {
        }

        try {
            mSimpleAdapter.getDropDownView(20, convertView, null);
            fail("Should throw IndexOutOfBoundsException if index is beyond the list's size");
        } catch (IndexOutOfBoundsException e) {
        }
    }

    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            method = "setViewBinder",
            args = {android.widget.SimpleAdapter.ViewBinder.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            method = "getViewBinder",
            args = {}
        )
    })
    public void testAccessViewBinder() {
        // no binder default
        assertNull(mSimpleAdapter.getViewBinder());

        // binder takes care of binding
        MockViewBinder binder = new MockViewBinder(true);
        mSimpleAdapter.setViewBinder(binder);
        assertSame(binder, mSimpleAdapter.getViewBinder());

        // binder try binding but fail
        binder = new MockViewBinder(false);
        mSimpleAdapter.setViewBinder(binder);
        assertSame(binder, mSimpleAdapter.getViewBinder());

        mSimpleAdapter.setViewBinder(null);
        assertNull(mSimpleAdapter.getViewBinder());
    }

    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Test {@link SimpleAdapter#setViewImage(ImageView, String)",
            method = "setViewImage",
            args = {android.widget.ImageView.class, java.lang.String.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Test {@link SimpleAdapter#setViewImage(ImageView, String)",
            method = "setViewImage",
            args = {android.widget.ImageView.class, int.class}
        )
    })
    @ToBeFixed(bug = "1417734", explanation = "should add @throws clause into javadoc of "
            + "SimpleAdapter#setViewImage(ImageView, String) if the param String is null")
    public void testSetViewImage() {
        // String represents resId
        ImageView view = new ImageView(mContext);
        assertNull(view.getDrawable());
        mSimpleAdapter.setViewImage(view, String.valueOf(com.android.cts.stub.R.drawable.scenery));
        BitmapDrawable d = (BitmapDrawable) mContext.getResources().getDrawable(
                com.android.cts.stub.R.drawable.scenery);
        WidgetTestUtils.assertEquals(d.getBitmap(),
                ((BitmapDrawable) view.getDrawable()).getBitmap());

        // blank
        view = new ImageView(mContext);
        assertNull(view.getDrawable());
        mSimpleAdapter.setViewImage(view, "");
        assertNull(view.getDrawable());

        // null
        view = new ImageView(mContext);
        assertNull(view.getDrawable());
        try {
            // Should declare NullPoinertException if the uri or value is null
            mSimpleAdapter.setViewImage(view, null);
            fail("Should throw NullPointerException if the uri or value is null");
        } catch (NullPointerException e) {
        }

        // resId
        view = new ImageView(mContext);
        assertNull(view.getDrawable());
        mSimpleAdapter.setViewImage(view, com.android.cts.stub.R.drawable.scenery);
        d = (BitmapDrawable) mContext.getResources()
                .getDrawable(com.android.cts.stub.R.drawable.scenery);
        WidgetTestUtils.assertEquals(d.getBitmap(),
                ((BitmapDrawable) view.getDrawable()).getBitmap());

        // illegal resid
        view = new ImageView(mContext);
        assertNull(view.getDrawable());
        mSimpleAdapter.setViewImage(view, Integer.MAX_VALUE);
        assertNull(view.getDrawable());

        // uri
        view = new ImageView(mContext);
        assertNull(view.getDrawable());
        try {
            mSimpleAdapter.setViewImage(view, SimpleCursorAdapterTest.createTestImage(mContext,
                    "testimage", com.android.cts.stub.R.raw.testimage));
            assertNotNull(view.getDrawable());
            Bitmap testBitmap = WidgetTestUtils.getUnscaledBitmap(mContext.getResources(),
                    com.android.cts.stub.R.raw.testimage);
            WidgetTestUtils.assertEquals(testBitmap,
                    ((BitmapDrawable) view.getDrawable()).getBitmap());
        } finally {
            SimpleCursorAdapterTest.destroyTestImage(mContext,"testimage");
        }
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#setViewText(TextView, String)}",
        method = "setViewText",
        args = {android.widget.TextView.class, java.lang.String.class}
    )
    public void testSetViewText() {
        TextView view = new TextView(mContext);
        mSimpleAdapter.setViewText(view, "expected");
        assertEquals("expected", view.getText().toString());

        mSimpleAdapter.setViewText(view, null);
        assertEquals("", view.getText().toString());
    }

    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Test {@link SimpleAdapter#getFilter()}",
        method = "getFilter",
        args = {}
    )
    public void testGetFilter() {
        assertNotNull(mSimpleAdapter.getFilter());
    }

    /**
     * Creates the test list.
     *
     * @param colCount the column count
     * @param rowCount the row count
     * @return the array list< hash map< string, string>>, Example:if the
     *         colCount = 2 and rowCount = 3, the list will be { {column0=>00,
     *         column1=>01}, {column0=>10, column1=>11}, {column0=>20,
     *         column1=>21} }
     */
    private ArrayList<HashMap<String, String>> createTestList(int colCount, int rowCount) {
        ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
        String[] columns = new String[colCount];
        for (int i = 0; i < colCount; i++) {
            columns[i] = "column" + i;
        }

        for (int i = 0; i < rowCount; i++) {
            HashMap<String, String> row = new HashMap<String, String>();
            for (int j = 0; j < colCount; j++) {
                row.put(columns[j], "" + i + "" + j);
            }
            list.add(row);
        }

        return list;
    }

    private class MockViewBinder implements ViewBinder {
        private boolean mExpectedResult;

        private boolean mHasCalledSetViewValue;

        public MockViewBinder(boolean expectedResult) {
            mExpectedResult = expectedResult;
        }

        public void reset(){
            mHasCalledSetViewValue = false;
        }

        public boolean hasCalledSetViewValue() {
            return mHasCalledSetViewValue;
        }

        public boolean setViewValue(View view, Object data, String textRepresentation) {
            mHasCalledSetViewValue = true;
            return mExpectedResult;
        }
    }
}
