/*
 * Copyright (C) 2020 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 com.android.car.ui.recyclerview;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isNotChecked;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import android.view.View;

import androidx.test.rule.ActivityTestRule;

import com.android.car.ui.tests.unit.R;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentMatchers;

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

/** Unit tests for {@link CarUiListItem}. */
public class CarUiListItemTest {

    private CarUiRecyclerView mCarUiRecyclerView;

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

    @Before
    public void setUp() {
        mCarUiRecyclerView = mActivityRule.getActivity().requireViewById(R.id.list);
    }

    @Test
    public void testItemVisibility_withTitle() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
        item.setTitle("Test title");
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.title)).check(matches(isDisplayed()));
        onView(withId(R.id.body)).check(matches(not(isDisplayed())));
        onView(withId(R.id.icon_container)).check(matches(not(isDisplayed())));
        onView(withId(R.id.action_container)).check(matches(not(isDisplayed())));
    }

    @Test
    public void testItemVisibility_withBody() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
        item.setBody("Test body");
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.body)).check(matches(isDisplayed()));
        onView(withId(R.id.title)).check(matches(not(isDisplayed())));
        onView(withId(R.id.icon_container)).check(matches(not(isDisplayed())));
        onView(withId(R.id.action_container)).check(matches(not(isDisplayed())));
    }

    @Test
    public void testItemVisibility_withTitle_withBodyAndIcon() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
        item.setTitle("Test title");
        item.setBody("Test body");
        item.setIcon(mActivityRule.getActivity().getDrawable(R.drawable.car_ui_icon_close));
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.title)).check(matches(isDisplayed()));
        onView(withId(R.id.body)).check(matches(isDisplayed()));
        onView(withId(R.id.icon_container)).check(matches(isDisplayed()));
        onView(withId(R.id.action_container)).check(matches(not(isDisplayed())));
    }

    @Test
    public void testItem_withCheckbox() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem.OnCheckedChangeListener mockOnCheckedChangeListener = mock(
                CarUiContentListItem.OnCheckedChangeListener.class);

        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.CHECK_BOX);
        item.setTitle("Test item with checkbox");
        item.setOnCheckedChangeListener(mockOnCheckedChangeListener);
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.title)).check(matches(isDisplayed()));
        onView(withId(R.id.checkbox_widget)).check(matches(isDisplayed()));
        onView(withId(R.id.action_divider)).check(matches(not(isDisplayed())));

        // List item with checkbox should be initially unchecked.
        onView(withId(R.id.checkbox_widget)).check(matches(isNotChecked()));
        // Clicks anywhere on the item should toggle the checkbox
        onView(withId(R.id.title)).perform(click());
        onView(withId(R.id.checkbox_widget)).check(matches(isChecked()));
        // Check that onCheckChangedListener was invoked.
        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, true);

        // Uncheck checkbox with click on the action container
        onView(withId(R.id.action_container)).perform(click());
        onView(withId(R.id.checkbox_widget)).check(matches(isNotChecked()));
        // Check that onCheckChangedListener was invoked.
        verify(mockOnCheckedChangeListener, times(1)).onCheckedChanged(item, false);
    }

    @Test
    public void testItem_withSwitch() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.SWITCH);
        item.setBody("Test item with switch");
        item.setChecked(true);
        item.setActionDividerVisible(true);
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.body)).check(matches(isDisplayed()));
        onView(withId(R.id.switch_widget)).check(matches(isDisplayed()));
        onView(withId(R.id.action_divider)).check(matches(isDisplayed()));

        // List item with checkbox should be initially checked.
        onView(withId(R.id.switch_widget)).check(matches(isChecked()));
        // Clicks anywhere on the item should toggle the switch
        onView(withId(R.id.switch_widget)).perform(click());
        onView(withId(R.id.switch_widget)).check(matches(isNotChecked()));
        // Uncheck checkbox with click on the action container
        onView(withId(R.id.body)).perform(click());
        onView(withId(R.id.switch_widget)).check(matches(isChecked()));
    }

    @Test
    public void testItem_withRadioButton() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem item = new CarUiContentListItem(
                CarUiContentListItem.Action.RADIO_BUTTON);
        item.setTitle("Test item with radio button");
        item.setChecked(false);
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.title)).check(matches(isDisplayed()));
        onView(withId(R.id.radio_button_widget)).check(matches(isDisplayed()));

        // List item with checkbox should be initially not checked.
        onView(withId(R.id.radio_button_widget)).check(matches(isNotChecked()));
        // Clicks anywhere on the item should toggle the radio button.
        onView(withId(R.id.radio_button_widget)).perform(click());
        onView(withId(R.id.radio_button_widget)).check(matches(isChecked()));

        // Repeated clicks on a selected radio button should not toggle the element once checked.
        onView(withId(R.id.title)).perform(click());
        onView(withId(R.id.radio_button_widget)).check(matches(isChecked()));
    }

    @Test
    public void testItem_withListener() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem.OnClickListener mockOnCheckedChangeListener = mock(
                CarUiContentListItem.OnClickListener.class);

        CarUiContentListItem item = new CarUiContentListItem(
                CarUiContentListItem.Action.NONE);
        item.setIcon(mActivityRule.getActivity().getDrawable(R.drawable.car_ui_icon_close));
        item.setTitle("Test item with listener");
        item.setBody("Body text");
        item.setOnItemClickedListener(mockOnCheckedChangeListener);
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.title)).check(matches(isDisplayed()));

        // Clicks anywhere on the item should toggle the listener
        onView(withId(R.id.title)).perform(click());
        verify(mockOnCheckedChangeListener, times(1)).onClick(item);

        onView(withId(R.id.body)).perform(click());
        verify(mockOnCheckedChangeListener, times(2)).onClick(item);

        onView(withId(R.id.icon_container)).perform(click());
        verify(mockOnCheckedChangeListener, times(3)).onClick(item);
    }

    @Test
    public void testItem_withSupplementalIconAndIconOnClickListener() {
        List<CarUiListItem> items = new ArrayList<>();

        CarUiContentListItem.OnClickListener mockedItemOnClickListener = mock(
                CarUiContentListItem.OnClickListener.class);
        View.OnClickListener mockedIconListener = mock(View.OnClickListener.class);

        CarUiContentListItem item = new CarUiContentListItem(
                CarUiContentListItem.Action.ICON);
        item.setSupplementalIcon(
                mActivityRule.getActivity().getDrawable(R.drawable.car_ui_icon_close),
                mockedIconListener);
        item.setOnItemClickedListener(mockedItemOnClickListener);
        item.setTitle("Test item with listeners");
        items.add(item);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiListItemAdapter(items)));

        onView(withId(R.id.title)).check(matches(isDisplayed()));

        // Clicks anywhere on the item (outside of the icon) should only invoke the item click
        // listener.
        onView(withId(R.id.title)).perform(click());
        verify(mockedItemOnClickListener, times(1)).onClick(item);

        // Clicks anywhere on the icon should invoke both listeners.
        onView(withId(R.id.action_container)).perform(click());
        verify(mockedItemOnClickListener, times(2)).onClick(item);
        verify(mockedIconListener, times(1)).onClick(ArgumentMatchers.any(View.class));
    }

    @Test
    public void testRadioButtonListItemAdapter() {
        List<CarUiRadioButtonListItem> items = new ArrayList<>();

        CarUiRadioButtonListItem itemOne = new CarUiRadioButtonListItem();
        String itemOneTitle = "Item 1";
        itemOne.setTitle(itemOneTitle);
        items.add(itemOne);

        CarUiRadioButtonListItem itemTwo = new CarUiRadioButtonListItem();
        String itemTwoTitle = "Item 2";
        itemTwo.setTitle(itemTwoTitle);
        items.add(itemTwo);

        CarUiRadioButtonListItem itemThree = new CarUiRadioButtonListItem();
        String itemThreeTitle = "Item 3";
        itemThree.setTitle(itemThreeTitle);
        items.add(itemThree);

        mCarUiRecyclerView.post(
                () -> mCarUiRecyclerView.setAdapter(new CarUiRadioButtonListItemAdapter(items)));

        onView(withText(itemOneTitle)).check(matches(isDisplayed()));
        onView(withText(itemTwoTitle)).check(matches(isDisplayed()));
        onView(withText(itemThreeTitle)).check(matches(isDisplayed()));

        // All items are initially unchecked.
        assertFalse(itemOne.isChecked());
        assertFalse(itemTwo.isChecked());
        assertFalse(itemThree.isChecked());

        // Select first item.
        onView(withText(itemOneTitle)).perform(click());
        assertTrue(itemOne.isChecked());
        assertFalse(itemTwo.isChecked());
        assertFalse(itemThree.isChecked());

        // Select second item.
        onView(withText(itemTwoTitle)).perform(click());
        assertFalse(itemOne.isChecked());
        assertTrue(itemTwo.isChecked());
        assertFalse(itemThree.isChecked());

        // Select third item.
        onView(withText(itemThreeTitle)).perform(click());
        assertFalse(itemOne.isChecked());
        assertFalse(itemTwo.isChecked());
        assertTrue(itemThree.isChecked());
    }
}
