package bou.amine.apps.readerforselfossv2.android

import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.action.ViewActions.typeTextIntoFocusedView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isChecked
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.isEnabled
import androidx.test.espresso.matcher.ViewMatchers.isFocused
import androidx.test.espresso.matcher.ViewMatchers.isRoot
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.not
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith


@RunWith(AndroidJUnit4::class)
@LargeTest
class SettingsActivityGeneralTest {

    @get:Rule
    val activityRule = ActivityScenarioRule(LoginActivity::class.java)

    @Before
    fun init() {
        loginAndInitHome()
        openActionBarOverflowOrOptionsMenu(
            ApplicationProvider.getApplicationContext()
        )
        onView(withText(R.string.title_activity_settings)).perform(click())
        onView(withText(R.string.pref_header_general)).perform(click())
    }

    @Test
    fun testGeneral() {
        onView(withText(R.string.pref_api_items_number_title)).check(matches(isDisplayed()))
        onView(
            withSettingsCheckboxWidget(R.string.pref_general_infinite_loading_title)
        ).check(
            matches(
                allOf(
                    isDisplayed(), not(isChecked())
                )
            )
        )
        onView(withText(R.string.pref_general_category_links)).check(matches(isDisplayed()))
        onView(withSettingsCheckboxWidget(R.string.pref_article_viewer_title)).check(
            matches(
                allOf(
                    isDisplayed(), isChecked()
                )
            )
        )
        onView(withSettingsCheckboxWidget(R.string.reader_static_bar_title)).check(
            matches(
                allOf(
                    isDisplayed(), not(isChecked())
                )
            )
        )
        onView(withSettingsCheckboxFrame(R.string.reader_static_bar_title)).check(
            matches(
                isEnabled()
            )
        )
        onView(withText(R.string.pref_general_category_displaying)).check(matches(isDisplayed()))
        onView(withSettingsCheckboxWidget(R.string.pref_switch_card_view_title)).check(
            matches(
                allOf(
                    isDisplayed(), not(isChecked())
                )
            )
        )
        onView(withSettingsCheckboxWidget(R.string.card_height_title)).check(
            matches(
                allOf(
                    isDisplayed(), not(isChecked())
                )
            )
        )
        onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(
            matches(
                not(isEnabled())
            )
        )
        onView(withSettingsCheckboxWidget(R.string.switch_unread_count_title)).check(
            matches(
                allOf(
                    isDisplayed(), isChecked()
                )
            )
        )
        onView(withSettingsCheckboxWidget(R.string.display_all_counts_title)).check(
            matches(
                allOf(
                    isDisplayed(), not(isChecked())
                )
            )
        )
    }

    @Test
    fun testGeneralActionsNumberItems() {
        onView(withText(R.string.pref_api_items_number_title)).perform(click())
        onView(withId(android.R.id.edit)).check(matches(isFocused()))

        // Value check
        onView(
            withId(android.R.id.edit)
        ).perform(replaceText("AVC"))
            .check(matches(withText("")))
        // TODO: should check message error. Not working for api level 30+
        onView(
            withId(android.R.id.edit)
        ).perform(replaceText("-1"))
            .check(matches(withText("")))
        // TODO: should check message error. Not working for api level 30+
        onView(
            withId(android.R.id.edit)
        ).perform(replaceText("300"))
            .check(matches(withText("")))
        onView(
            withId(android.R.id.edit)
        ).perform(typeTextIntoFocusedView("300"))
            .check(matches(withText("30")))
        onView(
            withId(android.R.id.edit)
        ).perform(replaceText("10"))
            .check(matches(withText("10")))
        onView(isRoot()).perform(ViewActions.pressBack())

        // Value saving
        changeAndCancelSetting("20", "10") {
            onView(withText(R.string.pref_api_items_number_title)).perform(click())
        }
        changeAndSaveSetting("20", "10") {
            onView(withText(R.string.pref_api_items_number_title)).perform(click())
        }
    }

    @Test
    fun testGeneralActionsCheckboxes() {
        // article viewer settings
        onView(withSettingsCheckboxFrame(R.string.reader_static_bar_title)).check(
            matches(
                isEnabled()
            )
        )
        onView(withSettingsCheckboxWidget(R.string.pref_article_viewer_title)).perform(click())
        onView(withSettingsCheckboxFrame(R.string.reader_static_bar_title)).check(
            matches(
                not(isEnabled())
            )
        )

        onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(matches(not(isEnabled())))
        onView(withSettingsCheckboxWidget(R.string.pref_switch_card_view_title)).perform(click())
        onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(matches(isEnabled()))
    }
}