/* 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 androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Assert
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.focus.activity.robots.notificationTray
import org.mozilla.focus.activity.robots.searchScreen
import org.mozilla.focus.helpers.FeatureSettingsHelper
import org.mozilla.focus.helpers.MainActivityFirstrunTestRule
import org.mozilla.focus.helpers.MockWebServerHelper
import org.mozilla.focus.helpers.TestAssetHelper.genericAsset
import org.mozilla.focus.helpers.TestHelper.mDevice
import org.mozilla.focus.helpers.TestHelper.pressHomeKey
import org.mozilla.focus.helpers.TestHelper.waitingTime
import org.mozilla.focus.helpers.TestSetup
import org.mozilla.focus.testAnnotations.SmokeTest
import java.io.IOException

// This test switches out of Focus and opens it from the private browsing notification
@RunWith(AndroidJUnit4ClassRunner::class)
class SwitchContextTest : TestSetup() {
    private lateinit var webServer: MockWebServer
    private val featureSettingsHelper = FeatureSettingsHelper()

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

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

        notificationTray {
            mDevice.openNotification()
            clearNotifications()
        }
    }

    @After
    fun tearDown() {
        try {
            webServer.shutdown()
        } catch (e: IOException) {
            throw AssertionError("Could not stop web server", e)
        }
        featureSettingsHelper.resetAllFeatureFlags()
    }

    @SmokeTest
    @Test
    fun notificationOpenButtonTest() {
        val testPage = webServer.genericAsset

        searchScreen {
        }.loadPage(testPage.url) {
            verifyPageContent(testPage.content)
        }
        // Send app to background
        pressHomeKey()
        // Pull down system bar and select Open
        mDevice.openNotification()
        notificationTray {
            verifySystemNotificationExists("Erase browsing history?")
            expandEraseBrowsingNotification()
        }.clickNotificationOpenButton {
            verifyBrowserView()
        }
    }

    @SmokeTest
    @Test
    fun switchFromSettingsToFocusTest() {
        // Initialize UiDevice instance
        val appLaunchTimeoutMillis = 5000
        val settingsPackage = "com.android.settings"
        val settingsApp = mDevice.findObject(
            UiSelector()
                .packageName(settingsPackage)
                .enabled(true),
        )
        val launcherPackage = mDevice.launcherPackageName
        val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
        val intent = context.packageManager
            .getLaunchIntentForPackage(settingsPackage)
        val testPage = webServer.genericAsset

        // Open a webpage
        searchScreen {
        }.loadPage(testPage.url) { }

        // Switch out of Focus, open settings app
        pressHomeKey()

        // Wait for launcher
        Assert.assertNotNull(launcherPackage)
        mDevice.wait(
            Until.hasObject(By.pkg(launcherPackage).depth(0)),
            appLaunchTimeoutMillis.toLong(),
        )

        // Launch the app
        context.startActivity(intent)
        settingsApp.waitForExists(waitingTime)
        assertTrue(settingsApp.exists())

        // switch to Focus
        mDevice.openNotification()
        notificationTray {
            verifySystemNotificationExists("Erase browsing history?")
            expandEraseBrowsingNotification()
        }.clickNotificationOpenButton {
            verifyBrowserView()
        }
    }
}
