/*
 * Copyright (C) 2012 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.view.accessibility.cts;

import android.graphics.Rect;
import android.os.Parcel;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.cts.accessibility.R;

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

/**
 * Class for testing {@link AccessibilityNodeInfo}.
 */
public class AccessibilityNodeInfoTest extends AndroidTestCase {

    /** The number of properties of the {@link AccessibilityNodeInfo} class. */
    private static final int NON_STATIC_FIELD_COUNT = 30;

    @SmallTest
    public void testMarshaling() throws Exception {
        // no new fields, so we are testing marshaling of all such
        AccessibilityRecordTest.assertNoNewNonStaticFieldsAdded(AccessibilityNodeInfo.class,
                NON_STATIC_FIELD_COUNT);

        // fully populate the node info to marshal
        AccessibilityNodeInfo sentInfo = AccessibilityNodeInfo.obtain(new View(getContext()));
        fullyPopulateAccessibilityNodeInfo(sentInfo);

        // marshal and unmarshal the node info
        Parcel parcel = Parcel.obtain();
        sentInfo.writeToParcel(parcel, 0);
        parcel.setDataPosition(0);
        AccessibilityNodeInfo receivedInfo = AccessibilityNodeInfo.CREATOR.createFromParcel(parcel);

        // make sure all fields properly marshaled
        assertEqualsAccessibilityNodeInfo(sentInfo, receivedInfo);
    }

    /**
     * Tests if {@link AccessibilityNodeInfo}s are properly reused.
     */
    @SmallTest
    public void testReuse() {
        AccessibilityEvent firstInfo = AccessibilityEvent.obtain();
        firstInfo.recycle();
        AccessibilityEvent secondInfo = AccessibilityEvent.obtain();
        assertSame("AccessibilityNodeInfo not properly reused", firstInfo, secondInfo);
    }

    /**
     * Tests if {@link AccessibilityNodeInfo} are properly recycled.
     */
    @SmallTest
    public void testRecycle() {
        // obtain and populate an node info
        AccessibilityNodeInfo populatedInfo = AccessibilityNodeInfo.obtain();
        fullyPopulateAccessibilityNodeInfo(populatedInfo);

        // recycle and obtain the same recycled instance
        populatedInfo.recycle();
        AccessibilityNodeInfo recycledInfo = AccessibilityNodeInfo.obtain();

        // check expectations
        assertAccessibilityNodeInfoCleared(recycledInfo);
    }

    /**
     * Tests whether the event describes its contents consistently.
     */
    @SmallTest
    public void testDescribeContents() {
        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
        assertSame("Accessibility node infos always return 0 for this method.", 0,
                info.describeContents());
        fullyPopulateAccessibilityNodeInfo(info);
        assertSame("Accessibility node infos always return 0 for this method.", 0,
                info.describeContents());
    }

    /**
     * Tests whether accessibility actions are properly added.
     */
    @SmallTest
    public void testAddActions() {
        List<AccessibilityAction> customActions = new ArrayList<AccessibilityAction>();
        customActions.add(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
        customActions.add(new AccessibilityAction(R.id.foo_custom_action, "Foo"));

        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
        for (AccessibilityAction customAction : customActions) {
            info.addAction(customAction);
        }

        assertSame(info.getActions(), (AccessibilityNodeInfo.ACTION_FOCUS
                | AccessibilityNodeInfo.ACTION_CLEAR_FOCUS));

        List<AccessibilityAction> allActions = new ArrayList<AccessibilityAction>();
        allActions.add(AccessibilityAction.ACTION_CLEAR_FOCUS);
        allActions.addAll(customActions);
        assertEquals(info.getActionList(), allActions);
    }

    /**
     * Tests whether we catch addition of an action with invalid id.
     */
    @SmallTest
    public void testCreateInvalidActionId() {
        try {
            new AccessibilityAction(3, null);
        } catch (IllegalArgumentException iae) {
            /* expected */
        }
    }

    /**
     * Tests whether accessibility actions are properly removed.
     */
    @SmallTest
    public void testRemoveActions() {
        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();

        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
        assertSame(info.getActions(), AccessibilityNodeInfo.ACTION_FOCUS);

        info.removeAction(AccessibilityNodeInfo.ACTION_FOCUS);
        assertSame(info.getActions(), 0);
        assertTrue(info.getActionList().isEmpty());

        AccessibilityAction customFocus = new AccessibilityAction(
                AccessibilityNodeInfo.ACTION_FOCUS, "Foo");
        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
        info.addAction(customFocus);
        assertSame(info.getActionList().size(), 1);
        assertEquals(info.getActionList().get(0), customFocus);
        assertSame(info.getActions(), AccessibilityNodeInfo.ACTION_FOCUS);

        info.removeAction(customFocus);
        assertSame(info.getActions(), 0);
        assertTrue(info.getActionList().isEmpty());
    }

    /**
     * Fully populates the {@link AccessibilityNodeInfo} to marshal.
     *
     * @param info The node info to populate.
     */
    private void fullyPopulateAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        info.setParent(new View(getContext()));
        info.setSource(new View(getContext()));
        info.addChild(new View(getContext()));
        info.addChild(new View(getContext()), 1);
        info.setBoundsInParent(new Rect(1,1,1,1));
        info.setBoundsInScreen(new Rect(2,2,2,2));
        info.setClassName("foo.bar.baz.Class");
        info.setContentDescription("content description");
        info.setPackageName("foo.bar.baz");
        info.setText("text");
        info.setCheckable(true);
        info.setChecked(true);
        info.setClickable(true);
        info.setEnabled(true);
        info.setFocusable(true);
        info.setFocused(true);
        info.setLongClickable(true);
        info.setContextClickable(true);
        info.setPassword(true);
        info.setScrollable(true);
        info.setSelected(true);
        info.addAction(AccessibilityNodeInfo.ACTION_FOCUS);
        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_FOCUS);
        info.addAction(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
        info.addAction(new AccessibilityAction(R.id.foo_custom_action, "Foo"));
        info.setAccessibilityFocused(true);
        info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE);
        info.setLabeledBy(new View(getContext()));
        info.setLabelFor(new View(getContext()));
        info.setViewIdResourceName("foo.bar:id/baz");
    }

    /**
     * Compares all properties of the <code>expectedInfo</code> and the
     * <code>receviedInfo</code> to verify that the received node info is
     * the one that is expected.
     */
    public static void assertEqualsAccessibilityNodeInfo(AccessibilityNodeInfo expectedInfo,
            AccessibilityNodeInfo receivedInfo) {
        Rect expectedBounds = new Rect();
        Rect receivedBounds = new Rect();
        expectedInfo.getBoundsInParent(expectedBounds);
        receivedInfo.getBoundsInParent(receivedBounds);
        assertEquals("boundsInParent has incorrect value", expectedBounds, receivedBounds);
        expectedInfo.getBoundsInScreen(expectedBounds);
        receivedInfo.getBoundsInScreen(receivedBounds);
        assertEquals("boundsInScreen has incorrect value", expectedBounds, receivedBounds);
        assertEquals("className has incorrect value", expectedInfo.getClassName(),
                receivedInfo.getClassName());
        assertEquals("contentDescription has incorrect value", expectedInfo.getContentDescription(),
                receivedInfo.getContentDescription());
        assertEquals("packageName has incorrect value", expectedInfo.getPackageName(),
                receivedInfo.getPackageName());
        assertEquals("text has incorrect value", expectedInfo.getText(), receivedInfo.getText());
        assertSame("checkable has incorrect value", expectedInfo.isCheckable(),
                receivedInfo.isCheckable());
        assertSame("checked has incorrect value", expectedInfo.isChecked(),
                receivedInfo.isChecked());
        assertSame("clickable has incorrect value", expectedInfo.isClickable(),
                receivedInfo.isClickable());
        assertSame("enabled has incorrect value", expectedInfo.isEnabled(),
                receivedInfo.isEnabled());
        assertSame("focusable has incorrect value", expectedInfo.isFocusable(),
                receivedInfo.isFocusable());
        assertSame("focused has incorrect value", expectedInfo.isFocused(),
                receivedInfo.isFocused());
        assertSame("longClickable has incorrect value", expectedInfo.isLongClickable(),
                receivedInfo.isLongClickable());
        assertSame("contextClickable has incorrect value", expectedInfo.isContextClickable(),
                receivedInfo.isContextClickable());
        assertSame("password has incorrect value", expectedInfo.isPassword(),
                receivedInfo.isPassword());
        assertSame("scrollable has incorrect value", expectedInfo.isScrollable(),
                receivedInfo.isScrollable());
        assertSame("selected has incorrect value", expectedInfo.isSelected(),
                receivedInfo.isSelected());
        assertSame("actions has incorrect value", expectedInfo.getActions(),
                receivedInfo.getActions());
        assertEquals("actionsSet has incorrect value", expectedInfo.getActionList(),
                receivedInfo.getActionList());
        assertSame("childCount has incorrect value", expectedInfo.getChildCount(),
                receivedInfo.getChildCount());
        assertSame("childCount has incorrect value", expectedInfo.getChildCount(),
                receivedInfo.getChildCount());
        assertSame("accessibilityFocused has incorrect value",
                expectedInfo.isAccessibilityFocused(),
                receivedInfo.isAccessibilityFocused());
        assertSame("movementGranularities has incorrect value",
                expectedInfo.getMovementGranularities(),
                receivedInfo.getMovementGranularities());
        assertEquals("viewId has incorrect value", expectedInfo.getViewIdResourceName(),
                receivedInfo.getViewIdResourceName());
    }

    /**
     * Asserts that an {@link AccessibilityNodeInfo} is cleared.
     *
     * @param info The node info to check.
     */
    public static void assertAccessibilityNodeInfoCleared(AccessibilityNodeInfo info) {
        Rect bounds = new Rect();
        info.getBoundsInParent(bounds);
        assertTrue("boundsInParent not properly recycled", bounds.isEmpty());
        info.getBoundsInScreen(bounds);
        assertTrue("boundsInScreen not properly recycled", bounds.isEmpty());
        assertNull("className not properly recycled", info.getClassName());
        assertNull("contentDescription not properly recycled", info.getContentDescription());
        assertNull("packageName not properly recycled", info.getPackageName());
        assertNull("text not properly recycled", info.getText());
        assertFalse("checkable not properly recycled", info.isCheckable());
        assertFalse("checked not properly recycled", info.isChecked());
        assertFalse("clickable not properly recycled", info.isClickable());
        assertFalse("enabled not properly recycled", info.isEnabled());
        assertFalse("focusable not properly recycled", info.isFocusable());
        assertFalse("focused not properly recycled", info.isFocused());
        assertFalse("longClickable not properly recycled", info.isLongClickable());
        assertFalse("contextClickable not properly recycled", info.isContextClickable());
        assertFalse("password not properly recycled", info.isPassword());
        assertFalse("scrollable not properly recycled", info.isScrollable());
        assertFalse("selected not properly recycled", info.isSelected());
        assertSame("actions not properly recycled", 0, info.getActions());
        assertFalse("accessibilityFocused not properly recycled", info.isAccessibilityFocused());
        assertSame("movementGranularities not properly recycled", 0,
                info.getMovementGranularities());
        assertNull("viewId not properly recycled", info.getViewIdResourceName());
    }
}
