// Tests if logging into all apps works using the admin user without SSO
// For SSO login tests see ./single-sign-on
const { openBrowser, goto, textBox, into, write, click, toRightOf, below, link, press, image, waitFor, closeBrowser, screenshot } = require('taiko');
const assert = require('assert');

(async () => {
  try {
    const taikoTests = process.env.TAIKO_TESTS || 'all'
    const domain = process.env.DOMAIN
    const globalTimeout = 60000

    // https://docs.taiko.dev/api/setconfig/
    // setConfig( { observeTime: 1000});
    setConfig( {
      observeTime: 0,
      // Navigation timeout value in milliseconds for navigation after performing openTab, goto, reload, goBack, goForward, click, write, clear, press and evaluate.
      navigationTimeout: globalTimeout,
      highlightOnAction: 'true'
    });

    console.log('Executing these tests: ' + taikoTests)
    await openBrowser({
      // Optimize chrome instances for docker an parallel runs, see:
      // https://docs.taiko.dev/taiko_in_docker/
      // https://docs.taiko.dev/frequently_asked_questions/#how-can-i-optimize-chrome-instances-for-parallel-runs%3F
      args: [
        "--disable-gpu",
        "--disable-dev-shm-usage",
        "--disable-setuid-sandbox",
        "--no-first-run",
        "--no-sandbox",
        "--no-zygote",
        "--start-maximized"
      ]
    });

    // Nextcloud and Onlyoffice
    if (taikoTests.includes('nextcloud') || taikoTests === 'all') {
      const nextcloudUrl = 'https://files.' + domain
      const onlyofficeUrl = 'https://office.' + domain
      const nextcloudUsername = process.env.NEXTCLOUD_USERNAME || 'admin'
      const nextcloudPassword = process.env.NEXTCLOUD_PASSWORD
      console.log('• Onlyoffice')

      await goto(onlyofficeUrl + '/welcome')
      await waitFor(async () => (await text("Thank you for choosing ONLYOFFICE!").isVisible()))
      await waitFor(async () => (await text("Document Server is running").isVisible()))

      await goto(onlyofficeUrl + '/healthcheck')
      await waitFor(async () => (await text("true").isVisible()))

      console.log('• Nextcloud')
      await goto(nextcloudUrl)
      await write(nextcloudUsername, into(textBox('Username')))
      await write(nextcloudPassword, into(textBox('Password')))

      await click('Log in')
      await waitFor(async () => (await text("Set location for weather").isVisible()), globalTimeout)
      // Close potential nextcloud first run wizard modal
      // https://github.com/nextcloud/firstrunwizard/issues/488
      // Unfortunately, we need to sleep a while since I haven't found a
      // good way that closes the modal *if* it pops up, since these
      // tests should also work on subsequent logins.
      await waitFor(5000)
      await press('Escape')

      // Test if calendar app is enabled
      await click('Calendar')
      await waitFor(async () => (await text("Settings & Import").isVisible()), globalTimeout)

      console.log('• Nextcloud Onlyoffice integration')
      // Open document and type some text
      await click('Files')
      // Force page reload because of random empty pages for files app
      // https://open.greenhost.net/openappstack/nextcloud/-/issues/973
      await reload()

      await waitFor(async () => (await link({class:'new'}).isVisible()), globalTimeout)
      await click(link({class:'new'}))
      await click('Document')

      // Create random file name because NC20 will complain if file already
      // exists
      const file_rand = 'test-' + Math.random().toString(16).substr(2, 12)
      await press([...file_rand, 'Enter'])
      await press('Enter')

      let italicButtonId = '#id-toolbar-btn-italic'
      await waitFor(async () => (await $(italicButtonId).isVisible()), globalTimeout)

      // Activate italic button
      let buttonStateBefore = await evaluate($(italicButtonId), (elem) => {return elem.getAttribute('class')})
      await assert.ok(!buttonStateBefore.includes('active'))
      await click($(italicButtonId))
      let buttonStateAfter = await evaluate($(italicButtonId), (elem) => {return elem.getAttribute('class')})
      await assert.ok(buttonStateAfter.includes('active'))

      await press([...'Hi from taiko!', 'Enter'])

      // Deactivate italic finially
      await click($(italicButtonId))
      await closeTab()
    }

    // Rocketchat
    if (taikoTests.includes('rocketchat') || taikoTests === 'all') {
      const rocketchatUrl = 'https://chat.' + domain
      const rocketchatUsername = process.env.ROCKETCHAT_USERNAME || 'admin'
      const rocketchatPassword = process.env.ROCKETCHAT_PASSWORD

      console.log('• Rocketchat')
      await goto(rocketchatUrl)
      await write(rocketchatUsername, into(textBox('Username')))
      await write(rocketchatPassword, into(textBox('Password')))
      await click('Login')
      await waitFor('Welcome to Rocket.Chat!')
    }

    // Wordpress
    if (taikoTests.includes('wordpress') || taikoTests === 'all') {
      const wordpressUrl = 'https://www.' + domain
      const wordpressUsername = process.env.WORDPRESS_USERNAME || 'admin'
      const wordpressPassword = process.env.WORDPRESS_PASSWORD

      console.log('• Wordpress')
      await goto(wordpressUrl)
      await click('Log in')
      await write(wordpressUsername, into(textBox('Username')))
      await write(wordpressPassword, into(textBox('Password')))
      await click('Log in')
      await assert.ok(await link('Dashboard').exists())
    }

    // Grafana
    if (taikoTests.includes('grafana') || taikoTests === 'all') {
      const grafanaUrl = 'https://grafana.' + domain
      const grafanaUsername = process.env.GRAFANA_USERNAME || 'admin'
      const grafanaPassword = process.env.GRAFANA_PASSWORD

      console.log('• Grafana')
      await goto(grafanaUrl)
      await write(grafanaUsername, into(textBox('Username')))
      await write(grafanaPassword, into(textBox('Password')))
      await click('Log in')

      // Node exporter dashboard
      // Couldn't select "Manage dashboards" from the sidebar menu easily,
      // so we just go there
      await goto(grafanaUrl + '/dashboards')
      await click(link('Nodes'))
      await('CPU Usage')

      // Explore Loki log messages
      await goto(grafanaUrl + '/explore')
      await click(image(toRightOf('Explore')))
      await click('Loki')
      await click('Log browser')
      await click('app')
      await click('cert-manager')
      await click('grafana')
      await click('Show logs')
    }

    // Wekan
    if (taikoTests.includes('wekan') || taikoTests === 'all') {
      const wekanUrl = 'https://wekan.' + domain

      console.log('• Wekan')
      await goto(wekanUrl)
      await click("Sign In with Oidc")
    }

  } catch (error) {
    await screenshot()
    console.error(error)
    process.exitCode = 1
  } finally {
    await closeBrowser()
  }
})()