/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.focus.activity

import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.focus.activity.robots.searchScreen
import org.mozilla.focus.helpers.FeatureSettingsHelper
import org.mozilla.focus.helpers.MainActivityIntentsTestRule
import org.mozilla.focus.helpers.MockWebServerHelper
import org.mozilla.focus.helpers.RetryTestRule
import org.mozilla.focus.helpers.StringsHelper.GMAIL_APP
import org.mozilla.focus.helpers.StringsHelper.PHONE_APP
import org.mozilla.focus.helpers.TestAssetHelper.getGenericTabAsset
import org.mozilla.focus.helpers.TestAssetHelper.htmlControlsPageAsset
import org.mozilla.focus.helpers.TestHelper.assertNativeAppOpens
import org.mozilla.focus.helpers.TestHelper.waitingTime
import org.mozilla.focus.helpers.TestSetup
import org.mozilla.focus.testAnnotations.SmokeTest

// These tests check that various web controls work properly
@RunWith(AndroidJUnit4ClassRunner::class)
class WebControlsTest : TestSetup() {
    private lateinit var webServer: MockWebServer

    private val featureSettingsHelper = FeatureSettingsHelper()

    @get:Rule
    val mActivityTestRule = MainActivityIntentsTestRule(showFirstRun = false)

    @Rule
    @JvmField
    val retryTestRule = RetryTestRule(3)

    @Before
    override fun setUp() {
        super.setUp()
        webServer = MockWebServer().apply {
            dispatcher = MockWebServerHelper.AndroidAssetDispatcher()
            start()
        }
        featureSettingsHelper.setCfrForTrackingProtectionEnabled(false)
        featureSettingsHelper.setSearchWidgetDialogEnabled(false)
    }

    @After
    fun tearDown() {
        webServer.shutdown()
        featureSettingsHelper.resetAllFeatureFlags()
    }

    @SmokeTest
    @Test
    fun verifyTextInputTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            progressBar.waitUntilGone(waitingTime)
            clickAndWriteTextInInputBox("wiki")
            clickSubmitTextInputButton()
            verifyPageContent("You entered: wiki")
        }
    }

    @SmokeTest
    @Test
    fun verifyDropdownMenuTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            progressBar.waitUntilGone(waitingTime)
            clickDropDownForm()
            selectDropDownOption("The National")
            clickSubmitDropDownButton()
            verifySelectedDropDownOption("The National")
        }
    }

    @SmokeTest
    @Test
    fun verifyExternalLinksTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            progressBar.waitUntilGone(waitingTime)
            clickLinkMatchingText("External link")
            progressBar.waitUntilGone(waitingTime)
            verifyPageURL("DuckDuckGo")
        }
    }

    @SmokeTest
    @Test
    fun emailLinkTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            clickLinkMatchingText("Email link")
            clickOpenLinksInAppsOpenButton()
            assertNativeAppOpens(GMAIL_APP)
        }
    }

    @SmokeTest
    @Test
    fun telephoneLinkTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            clickLinkMatchingText("Telephone link")
            clickOpenLinksInAppsOpenButton()
            assertNativeAppOpens(PHONE_APP)
        }
    }

    @SmokeTest
    @Test
    fun verifyDismissTextSelectionToolbarTest() {
        val tab1Url = webServer.getGenericTabAsset(1).url
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(tab1Url) {
            progressBar.waitUntilGone(waitingTime)
        }.openSearchBar {
        }.loadPage(htmlControlsPage) {
            progressBar.waitUntilGone(waitingTime)
            longClickText("Copy")
        }.goToPreviousPage {
            verifyCopyOptionDoesNotExist()
        }
    }

    @Ignore("Failing, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1841006")
    @SmokeTest
    @Test
    fun verifySelectTextTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            progressBar.waitUntilGone(waitingTime)
            longClickAndCopyText("Copy")
            clickAndPasteTextInInputBox()
            clickSubmitTextInputButton()
            verifyPageContent("You entered: Copy")
        }
    }

    @SmokeTest
    @Test
    fun verifyCalendarFormTest() {
        val htmlControlsPage = webServer.htmlControlsPageAsset.url

        searchScreen {
        }.loadPage(htmlControlsPage) {
            progressBar.waitUntilGone(waitingTime)
            clickCalendarForm()
            selectDate()
            clickButtonWithText("Set")
            clickSubmitDateButton()
            verifySelectedDate()
        }
    }
}
