package bou.amine.apps.readerforselfossv2.android

import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.graphics.drawable.toBitmap
import androidx.test.espresso.Root
import androidx.test.espresso.matcher.RootMatchers.isPlatformPopup
import androidx.test.espresso.matcher.ViewMatchers.hasSibling
import androidx.test.espresso.matcher.ViewMatchers.withChild
import androidx.test.espresso.matcher.ViewMatchers.withClassName
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withParent
import androidx.test.espresso.matcher.ViewMatchers.withResourceName
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers
import org.hamcrest.TypeSafeMatcher


fun withError(@StringRes id: Int): TypeSafeMatcher<View?> {
    return object : TypeSafeMatcher<View?>() {
        override fun matchesSafely(view: View?): Boolean {
            if (view == null) {
                return false
            }
            val context = view.context
            if (view !is EditText) {
                return false
            }
            if (view.error == null) {
                return false
            }

            return view.error.toString() == context.getString(id)
        }

        override fun describeTo(description: Description?) {
        }
    }
}

fun isPopupWindow(): Matcher<Root> {
    return isPlatformPopup()
}

fun withDrawable(@DrawableRes id: Int) = object : TypeSafeMatcher<View>() {
    override fun describeTo(description: Description) {
        description.appendText("ImageView with drawable same as drawable with id $id")
    }

    override fun matchesSafely(view: View): Boolean {
        val context = view.context
        val expectedBitmap = context.getDrawable(id)!!.toBitmap()
        try {
            return view is ImageView && view.drawable.toBitmap().sameAs(expectedBitmap)
        } catch (e: Exception) {
            return false
        }
    }
}

fun hasBottombarItemText(@StringRes id: Int): Matcher<View>? {
    return allOf(
        withResourceName("fixed_bottom_navigation_icon"),
        withParent(
            allOf(
                withResourceName("fixed_bottom_navigation_icon_container"),
                hasSibling(withText(id))
            )
        )
    )
}

fun withSettingsCheckboxWidget(@StringRes id: Int): Matcher<View>? {
    return allOf(
        withId(android.R.id.switch_widget),
        withParent(
            withSettingsCheckboxFrame(id)
        )
    )
}

fun withSettingsCheckboxFrame(@StringRes id: Int): Matcher<View>? {
    return allOf(
        withId(android.R.id.widget_frame),
        hasSibling(
            allOf(
                withClassName(Matchers.equalTo(RelativeLayout::class.java.name)),
                withChild(
                    withText(id)
                )
            )
        )
    )
}