// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

/**
 * @fileoverview Provides extensions for
 * [Jasmine](https://jasmine.github.io) and [Mocha](https://mochajs.org).
 *
 * You may conditionally suppress a test function using the exported
 * "ignore" function. If the provided predicate returns true, the attached
 * test case will be skipped:
 *
 *     test.ignore(maybe()).it('is flaky', function() {
 *       if (Math.random() < 0.5) throw Error();
 *     });
 *
 *     function maybe() { return Math.random() < 0.5; }
 */

'use strict'

const { isatty } = require('tty')
const chrome = require('../chrome')
const edge = require('../edge')
const firefox = require('../firefox')
const ie = require('../ie')
const remote = require('../remote')
const safari = require('../safari')
const { Browser } = require('../lib/capabilities')
const { Builder } = require('../index')

/**
 * Describes a browser targeted by a {@linkplain suite test suite}.
 * @record
 */
function TargetBrowser() {}

/**
 * The {@linkplain Browser name} of the targeted browser.
 * @type {string}
 */
TargetBrowser.prototype.name

/**
 * The specific version of the targeted browser, if any.
 * @type {(string|undefined)}
 */
TargetBrowser.prototype.version

/**
 * The specific {@linkplain ../lib/capabilities.Platform platform} for the
 * targeted browser, if any.
 * @type {(string|undefined)}.
 */
TargetBrowser.prototype.platform

/** @suppress {checkTypes} */
function color(c, s) {
  return isatty(process.stdout) ? `\u001b[${c}m${s}\u001b[0m` : s
}
function green(s) {
  return color(32, s)
}
function cyan(s) {
  return color(36, s)
}
function info(msg) {
  console.info(`${green('[INFO]')} ${msg}`)
}
function warn(msg) {
  console.warn(`${cyan('[WARNING]')} ${msg}`)
}

/**
 * Extracts the browsers for a test suite to target from the `SELENIUM_BROWSER`
 * environment variable.
 *
 * @return {{name: string, version: string, platform: string}}[] the browsers to target.
 */
function getBrowsersToTestFromEnv() {
  let browsers = process.env['SELENIUM_BROWSER']
  if (!browsers) {
    return []
  }
  return browsers.split(',').map((spec) => {
    const parts = spec.split(/:/, 3)
    let name = parts[0]
    if (name === 'ie') {
      name = Browser.INTERNET_EXPLORER
    } else if (name === 'edge') {
      name = Browser.EDGE
    }
    let version = parts[1]
    let platform = parts[2]
    return { name, version, platform }
  })
}

/**
 * @return {!Array<!TargetBrowser>} the browsers available for testing on this
 *     system.
 */
function getAvailableBrowsers() {
  info(`Searching for WebDriver executables installed on the current system...`)

  let targets = [
    [chrome.locateSynchronously, Browser.CHROME],
    [edge.locateSynchronously, Browser.EDGE],
    [firefox.locateSynchronously, Browser.FIREFOX],
    [ie.locateSynchronously, Browser.INTERNET_EXPLORER],
    [safari.locateSynchronously, Browser.SAFARI],
  ]

  let availableBrowsers = []
  for (let pair of targets) {
    const fn = pair[0]
    const name = pair[1]
    const capabilities = pair[2]
    if (fn()) {
      info(`... located ${name}`)
      availableBrowsers.push({ name, capabilities })
    }
  }

  if (availableBrowsers.length === 0) {
    warn(`Unable to locate any WebDriver executables for testing`)
  }

  return availableBrowsers
}

let wasInit
let targetBrowsers
let seleniumJar
let seleniumUrl
let seleniumServer

/**
 * Initializes this module by determining which browsers a
 * {@linkplain ./index.suite test suite} should run against. The default
 * behavior is to run tests against every browser with a WebDriver executables
 * (chromedriver, firefoxdriver, etc.) are installed on the system by `PATH`.
 *
 * Specific browsers can be selected at runtime by setting the
 * `SELENIUM_BROWSER` environment variable. This environment variable has the
 * same semantics as  with the WebDriver {@link ../index.Builder Builder},
 * except you may use a comma-delimited list to run against multiple browsers:
 *
 *     SELENIUM_BROWSER=chrome,firefox mocha --recursive tests/
 *
 * The `SELENIUM_REMOTE_URL` environment variable may be set to configure tests
 * to run against an externally managed (usually remote) Selenium server. When
 * set, the WebDriver builder provided by each
 * {@linkplain TestEnvironment#builder TestEnvironment} will automatically be
 * configured to use this server instead of starting a browser driver locally.
 *
 * The `SELENIUM_SERVER_JAR` environment variable may be set to the path of a
 * standalone Selenium server on the local machine that should be used for
 * WebDriver sessions. When set, the WebDriver builder provided by each
 * {@linkplain TestEnvironment} will automatically be configured to use the
 * started server instead of using a browser driver directly. It should only be
 * necessary to set the `SELENIUM_SERVER_JAR` when testing locally against
 * browsers not natively supported by the WebDriver
 * {@link ../index.Builder Builder}.
 *
 * When either of the `SELENIUM_REMOTE_URL` or `SELENIUM_SERVER_JAR` environment
 * variables are set, the `SELENIUM_BROWSER` variable must also be set.
 *
 * @param {boolean=} force whether to force this module to re-initialize and
 *     scan `process.env` again to determine which browsers to run tests
 *     against.
 */
function init(force = false) {
  if (wasInit && !force) {
    return
  }
  wasInit = true

  // If force re-init, kill the current server if there is one.
  if (seleniumServer) {
    seleniumServer.kill()
    seleniumServer = null
  }

  seleniumJar = process.env['SELENIUM_SERVER_JAR']
  seleniumUrl = process.env['SELENIUM_REMOTE_URL']
  if (seleniumJar) {
    info(`Using Selenium server jar: ${seleniumJar}`)
  }

  if (seleniumUrl) {
    info(`Using Selenium remote end: ${seleniumUrl}`)
  }

  if (seleniumJar && seleniumUrl) {
    throw Error(
      'Ambiguous test configuration: both SELENIUM_REMOTE_URL' +
        ' && SELENIUM_SERVER_JAR environment variables are set'
    )
  }

  const envBrowsers = getBrowsersToTestFromEnv()
  if ((seleniumJar || seleniumUrl) && envBrowsers.length === 0) {
    throw Error(
      'Ambiguous test configuration: when either the SELENIUM_REMOTE_URL or' +
        ' SELENIUM_SERVER_JAR environment variable is set, the' +
        ' SELENIUM_BROWSER variable must also be set.'
    )
  }

  targetBrowsers = envBrowsers.length > 0 ? envBrowsers : getAvailableBrowsers()
  info(
    `Running tests against [${targetBrowsers.map((b) => b.name).join(', ')}]`
  )

  after(function () {
    if (seleniumServer) {
      return seleniumServer.kill()
    }
  })
}

const TARGET_MAP = /** !WeakMap<!Environment, !TargetBrowser> */ new WeakMap()
const URL_MAP =
  /** !WeakMap<!Environment, ?(string|remote.SeleniumServer)> */ new WeakMap()

/**
 * Defines the environment a {@linkplain suite test suite} is running against.
 * @final
 */
class Environment {
  /**
   * @param {!TargetBrowser} browser the browser targetted in this environment.
   * @param {?(string|remote.SeleniumServer)=} url remote URL of an existing
   *     Selenium server to test against.
   */
  constructor(browser, url = undefined) {
    browser = /** @type {!TargetBrowser} */ (
      Object.seal(Object.assign({}, browser))
    )

    TARGET_MAP.set(this, browser)
    URL_MAP.set(this, url || null)
  }

  /** @return {!TargetBrowser} the target browser for this test environment. */
  get browser() {
    return TARGET_MAP.get(this)
  }

  /**
   * Returns a predicate function that will suppress tests in this environment
   * if the {@linkplain #browser current browser} is in the list of
   * `browsersToIgnore`.
   *
   * @param {...(string|!Browser)} browsersToIgnore the browsers that should
   *     be ignored.
   * @return {function(): boolean} a new predicate function.
   */
  browsers(...browsersToIgnore) {
    return () => browsersToIgnore.indexOf(this.browser.name) !== -1
  }

  /**
   * @return {!Builder} a new WebDriver builder configured to target this
   *     environment's {@linkplain #browser browser}.
   */
  builder() {
    const browser = this.browser
    const urlOrServer = URL_MAP.get(this)

    const builder = new Builder()
    builder.disableEnvironmentOverrides()

    const realBuild = builder.build
    builder.build = function () {
      builder.forBrowser(browser.name, browser.version, browser.platform)

      if (browser.capabilities) {
        builder.getCapabilities().merge(browser.capabilities)
      }

      if (browser.name === 'firefox') {
        builder.setCapability('moz:debuggerAddress', true)
      }

      if (typeof urlOrServer === 'string') {
        builder.usingServer(urlOrServer)
      } else if (urlOrServer) {
        builder.usingServer(urlOrServer.address())
      }
      return realBuild.call(builder)
    }

    return builder
  }
}

/**
 * Configuration options for a {@linkplain ./index.suite test suite}.
 * @record
 */
function SuiteOptions() {}

/**
 * The browsers to run the test suite against.
 * @type {!Array<!(Browser|TargetBrowser)>}
 */
SuiteOptions.prototype.browsers

let inSuite = false

/**
 * Defines a test suite by calling the provided function once for each of the
 * target browsers. If a suite is not limited to a specific set of browsers in
 * the provided {@linkplain ./index.SuiteOptions suite options}, the suite will
 * be configured to run against each of the {@linkplain ./index.init runtime
 * target browsers}.
 *
 * Sample usage:
 *
 *     const {By, Key, until} = require('selenium-webdriver');
 *     const {suite} = require('selenium-webdriver/testing');
 *
 *     suite(function(env) {
 *       describe('Google Search', function() {
 *         let driver;
 *
 *         before(async function() {
 *           driver = await env.builder().build();
 *         });
 *
 *         after(() => driver.quit());
 *
 *         it('demo', async function() {
 *           await driver.get('http://www.google.com/ncr');
 *
 *           let q = await driver.findElement(By.name('q'));
 *           await q.sendKeys('webdriver', Key.RETURN);
 *           await driver.wait(
 *               until.titleIs('webdriver - Google Search'), 1000);
 *         });
 *       });
 *     });
 *
 * By default, this example suite will run against every WebDriver-enabled
 * browser on the current system. Alternatively, the `SELENIUM_BROWSER`
 * environment variable may be used to run against a specific browser:
 *
 *     SELENIUM_BROWSER=firefox mocha -t 120000 example_test.js
 *
 * @param {function(!Environment)} fn the function to call to build the test
 *     suite.
 * @param {SuiteOptions=} options configuration options.
 */
function suite(fn, options = undefined) {
  if (inSuite) {
    throw Error('Calls to suite() may not be nested')
  }
  try {
    init()
    inSuite = true

    const suiteBrowsers = new Map()
    if (options && options.browsers) {
      for (let browser of options.browsers) {
        if (typeof browser === 'string') {
          suiteBrowsers.set(browser, { name: browser })
        } else {
          suiteBrowsers.set(browser.name, browser)
        }
      }
    }

    for (let browser of targetBrowsers) {
      if (suiteBrowsers.size > 0 && !suiteBrowsers.has(browser.name)) {
        continue
      }

      describe(`[${browser.name}]`, function () {
        if (!seleniumUrl && seleniumJar && !seleniumServer) {
          seleniumServer = new remote.SeleniumServer(seleniumJar)

          const startTimeout = 65 * 1000
          // eslint-disable-next-line no-inner-declarations
          function startSelenium() {
            if (typeof this.timeout === 'function') {
              this.timeout(startTimeout) // For mocha.
            }

            info(`Starting selenium server ${seleniumJar}`)
            return seleniumServer.start(60 * 1000)
          }

          const /** !Function */ beforeHook = global.beforeAll || global.before
          beforeHook(startSelenium, startTimeout)
        }

        fn(new Environment(browser, seleniumUrl || seleniumServer))
      })
    }
  } finally {
    inSuite = false
  }
}

/**
 * Returns an object with wrappers for the standard mocha/jasmine test
 * functions: `describe` and `it`, which will redirect to `xdescribe` and `xit`,
 * respectively, if provided predicate function returns false.
 *
 * Sample usage:
 *
 *     const {Browser} = require('selenium-webdriver');
 *     const {suite, ignore} = require('selenium-webdriver/testing');
 *
 *     suite(function(env) {
 *
 *         // Skip tests the current environment targets Chrome.
 *         ignore(env.browsers(Browser.CHROME)).
 *         describe('something', async function() {
 *           let driver = await env.builder().build();
 *           // etc.
 *         });
 *     });
 *
 * @param {function(): boolean} predicateFn A predicate to call to determine
 *     if the test should be suppressed. This function MUST be synchronous.
 * @return {{describe: !Function, it: !Function}} an object with wrapped
 *     versions of the `describe` and `it` test functions.
 */
function ignore(predicateFn) {
  const isJasmine = global.jasmine && typeof global.jasmine === 'object'

  const hooks = {
    describe: getTestHook('describe'),
    xdescribe: getTestHook('xdescribe'),
    it: getTestHook('it'),
    xit: getTestHook('xit'),
  }
  hooks.fdescribe = isJasmine ? getTestHook('fdescribe') : hooks.describe.only
  hooks.fit = isJasmine ? getTestHook('fit') : hooks.it.only

  let describe = wrap(hooks.xdescribe, hooks.describe)
  let fdescribe = wrap(hooks.xdescribe, hooks.fdescribe)
  //eslint-disable-next-line no-only-tests/no-only-tests
  describe.only = fdescribe

  let it = wrap(hooks.xit, hooks.it)
  let fit = wrap(hooks.xit, hooks.fit)
  //eslint-disable-next-line no-only-tests/no-only-tests
  it.only = fit

  return { describe, it }

  function wrap(onSkip, onRun) {
    return function (...args) {
      if (predicateFn()) {
        onSkip(...args)
      } else {
        onRun(...args)
      }
    }
  }
}

/**
 * @param {string} name
 * @return {!Function}
 * @throws {TypeError}
 */
function getTestHook(name) {
  let fn = global[name]
  let type = typeof fn
  if (type !== 'function') {
    throw TypeError(
      `Expected global.${name} to be a function, but is ${type}.` +
        ' This can happen if you try using this module when running with' +
        ' node directly instead of using jasmine or mocha'
    )
  }
  return fn
}

// PUBLIC API

module.exports = {
  Environment,
  SuiteOptions,
  init,
  ignore,
  suite,
}
