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

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.hasChildCount;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withHint;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static com.android.car.ui.actions.ViewActions.waitForView;
import static com.android.car.ui.matchers.ViewMatchers.nthChildOfView;
import static com.android.car.ui.matchers.ViewMatchers.withDrawable;

import static com.google.common.truth.Truth.assertThat;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;

import static org.hamcrest.core.IsNot.not;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.app.Activity;
import android.view.View;

import androidx.test.rule.ActivityTestRule;

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

import org.hamcrest.Matcher;
import org.junit.Rule;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.function.Consumer;

/** Unit test for {@link ToolbarController}. */
public class ToolbarTest {

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

    @Test
    public void test_setTitle_displaysTitle() throws Throwable {
        runWithToolbar((toolbar) -> toolbar.setTitle("Test title"));

        onView(withText("Test title")).check(matches(isDisplayed()));
    }

    @Test
    public void test_setSubtitle_displaysSubtitle() throws Throwable {
        runWithToolbar((toolbar) -> toolbar.setSubtitle("Test subtitle"));

        onView(withText("Test subtitle")).check(matches(isDisplayed()));
    }

    @Test
    public void test_setSearchHint_isDisplayed() throws Throwable {
        runWithToolbar((toolbar) -> {
            toolbar.setSearchHint("Test search hint");
            toolbar.setState(Toolbar.State.SEARCH);
        });

        onView(withHint("Test search hint")).check(matches(isDisplayed()));
    }

    @Test
    public void setters_and_getters_test() throws Throwable {
        runWithToolbar((toolbar) -> {
            toolbar.setTitle("Foo");
            toolbar.setSearchHint("Foo2");
            toolbar.setShowMenuItemsWhileSearching(true);
            toolbar.setState(Toolbar.State.SUBPAGE);
            toolbar.setNavButtonMode(Toolbar.NavButtonMode.CLOSE);

            assertThat(toolbar.getTitle().toString()).isEqualTo("Foo");
            assertThat(toolbar.getSearchHint().toString()).isEqualTo("Foo2");
            assertThat(toolbar.getShowMenuItemsWhileSearching()).isEqualTo(true);
            assertThat(toolbar.getState()).isEquivalentAccordingToCompareTo(Toolbar.State.SUBPAGE);
            assertThat(toolbar.getNavButtonMode()).isEquivalentAccordingToCompareTo(
                    Toolbar.NavButtonMode.CLOSE);
        });
    }

    @Test
    public void test_setLogo_displaysLogo() throws Throwable {
        runWithToolbar((toolbar) -> toolbar.setLogo(R.drawable.ic_launcher));

        onView(withDrawable(R.drawable.ic_launcher)).check(matches(isDisplayed()));
    }

    @Test
    public void pressBack_withoutListener_callsActivityOnBack() throws Throwable {
        runWithToolbar((toolbar) -> toolbar.setState(Toolbar.State.SUBPAGE));

        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());

        assertTrue(mActivityRule.getActivity().isFinishing());
        assertEquals(mActivityRule.getActivityResult().getResultCode(), Activity.RESULT_CANCELED);
    }

    @Test
    public void pressBack_withListenerThatReturnsFalse_callsActivityOnBack() throws Throwable {
        runWithToolbar((toolbar) -> {
            toolbar.setState(Toolbar.State.SUBPAGE);
            toolbar.registerOnBackListener(() -> false);
        });

        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());

        assertTrue(mActivityRule.getActivity().isFinishing());
        assertEquals(mActivityRule.getActivityResult().getResultCode(), Activity.RESULT_CANCELED);
    }

    @Test
    public void pressBack_withListenerThatReturnsTrue_doesntCallActivityOnBack() throws Throwable {
        runWithToolbar((toolbar) -> {
            toolbar.setState(Toolbar.State.SUBPAGE);
            toolbar.registerOnBackListener(() -> true);
        });

        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());

        assertFalse(mActivityRule.getActivity().isFinishing());
    }

    @Test
    public void pressBack_withUnregisteredListener_doesntCallActivityOnBack() throws Throwable {
        runWithToolbar((toolbar) -> {
            toolbar.setState(Toolbar.State.SUBPAGE);
            Toolbar.OnBackListener listener = () -> true;
            toolbar.registerOnBackListener(listener);
            toolbar.registerOnBackListener(listener);
            toolbar.unregisterOnBackListener(listener);
        });

        onView(withId(R.id.car_ui_toolbar_nav_icon_container)).perform(click());

        assertTrue(mActivityRule.getActivity().isFinishing());
    }

    @Test
    public void menuItems_setId_shouldWork() {
        MenuItem item = MenuItem.builder(mActivityRule.getActivity()).build();

        assertThat(item.getId()).isEqualTo(View.NO_ID);

        item.setId(7);

        assertThat(item.getId()).isEqualTo(7);
    }

    @Test
    public void menuItems_whenClicked_shouldCallListener() throws Throwable {
        MenuItem.OnClickListener callback = mock(MenuItem.OnClickListener.class);
        MenuItem menuItem = MenuItem.builder(mActivityRule.getActivity())
                .setTitle("Button!")
                .setOnClickListener(callback)
                .build();
        runWithToolbar((toolbar) -> toolbar.setMenuItems(Collections.singletonList(menuItem)));

        waitForMenuItems();

        onView(firstMenuItem()).perform(click());

        verify(callback).onClick(menuItem);
    }

    @Test
    public void menuItems_null_shouldRemoveExistingMenuItems() throws Throwable {
        runWithToolbar((toolbar) ->
                toolbar.setMenuItems(Arrays.asList(
                        MenuItem.builder(mActivityRule.getActivity())
                                .setTitle("Button!")
                                .build(),
                        MenuItem.builder(mActivityRule.getActivity())
                                .setTitle("Button2!")
                                .build()
                )));
        waitForMenuItems();

        onView(withId(R.id.car_ui_toolbar_menu_items_container)).check(matches(hasChildCount(2)));

        runWithToolbar((toolbar) -> toolbar.setMenuItems(null));

        onView(withId(R.id.car_ui_toolbar_menu_items_container)).check(matches(hasChildCount(0)));
    }

    @Test
    public void menuItems_setVisibility_shouldHide() throws Throwable {
        MenuItem menuItem = MenuItem.builder(mActivityRule.getActivity())
                .setTitle("Button!")
                .build();
        runWithToolbar((toolbar) -> toolbar.setMenuItems(Collections.singletonList(menuItem)));
        waitForMenuItems();

        onView(withText("Button!")).check(matches(isDisplayed()));

        runWithToolbar((toolbar) -> menuItem.setVisible(false));

        onView(withText("Button!")).check(matches(not(isDisplayed())));
    }

    @Test
    public void menuItems_searchScreen_shouldHideMenuItems() throws Throwable {
        runWithToolbar((toolbar) -> {
            toolbar.setMenuItems(Arrays.asList(
                    MenuItem.builder(mActivityRule.getActivity())
                            .setToSearch()
                            .build(),
                    MenuItem.builder(mActivityRule.getActivity())
                            .setTitle("Button!")
                            .build()));
            toolbar.setShowMenuItemsWhileSearching(false);
            toolbar.setState(Toolbar.State.SEARCH);
        });
        waitForMenuItems();

        // All menuitems should be hidden if we're hiding menuitems while searching
        onView(withText("Button!")).check(matches(not(isDisplayed())));
        onView(firstMenuItem()).check(matches(not(isDisplayed())));

        runWithToolbar((toolbar) -> toolbar.setShowMenuItemsWhileSearching(true));

        // Even if not hiding MenuItems while searching, the search MenuItem should still be hidden
        onView(withText("Button!")).check(matches(isDisplayed()));
        onView(firstMenuItem()).check(matches(not(isDisplayed())));
    }

    private void runWithToolbar(Consumer<ToolbarController> toRun) throws Throwable {
        mActivityRule.runOnUiThread(() -> {
            ToolbarController toolbar = CarUi.requireToolbar(mActivityRule.getActivity());
            toRun.accept(toolbar);
        });
    }

    private Matcher<View> firstMenuItem() {
        return nthChildOfView(withId(R.id.car_ui_toolbar_menu_items_container), 0);
    }

    private void waitForMenuItems() {
        onView(isRoot()).perform(waitForView(firstMenuItem(), 500));
    }
}
