// 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 Defines an environment agnostic {@linkplain cmd.Executor
 * command executor} that communicates with a remote end using JSON over HTTP.
 *
 * Clients should implement the {@link Client} interface, which is used by
 * the {@link Executor} to send commands to the remote end.
 */

'use strict'

const path = require('path')
const cmd = require('./command')
const error = require('./error')
const logging = require('./logging')
const promise = require('./promise')
const { Session } = require('./session')
const webElement = require('./webelement')
const { isObject } = require('./util')

const getAttribute = requireAtom(
  'get-attribute.js',
  '//javascript/node/selenium-webdriver/lib/atoms:get-attribute.js'
)
const isDisplayed = requireAtom(
  'is-displayed.js',
  '//javascript/node/selenium-webdriver/lib/atoms:is-displayed.js'
)
const findElements = requireAtom(
  'find-elements.js',
  '//javascript/node/selenium-webdriver/lib/atoms:find-elements.js'
)

/**
 * @param {string} module
 * @param {string} bazelTarget
 * @return {!Function}
 */
function requireAtom(module, bazelTarget) {
  try {
    return require('./atoms/' + module)
  } catch (ex) {
    try {
      const file = bazelTarget.slice(2).replace(':', '/')
      console.log(`../../../bazel-bin/${file}`)
      return require(path.resolve(`../../../bazel-bin/${file}`))
    } catch (ex2) {
      console.log(ex2)
      throw Error(
        `Failed to import atoms module ${module}. If running in dev mode, you` +
          ` need to run \`bazel build ${bazelTarget}\` from the project` +
          `root: ${ex}`
      )
    }
  }
}

/**
 * Converts a headers map to a HTTP header block string.
 * @param {!Map<string, string>} headers The map to convert.
 * @return {string} The headers as a string.
 */
function headersToString(headers) {
  const ret = []
  headers.forEach(function (value, name) {
    ret.push(`${name.toLowerCase()}: ${value}`)
  })
  return ret.join('\n')
}

/**
 * Represents a HTTP request message. This class is a "partial" request and only
 * defines the path on the server to send a request to. It is each client's
 * responsibility to build the full URL for the final request.
 * @final
 */
class Request {
  /**
   * @param {string} method The HTTP method to use for the request.
   * @param {string} path The path on the server to send the request to.
   * @param {Object=} opt_data This request's non-serialized JSON payload data.
   */
  constructor(method, path, opt_data) {
    this.method = /** string */ method
    this.path = /** string */ path
    this.data = /** Object */ opt_data
    this.headers = /** !Map<string, string> */ new Map([
      ['Accept', 'application/json; charset=utf-8'],
    ])
  }

  /** @override */
  toString() {
    let ret = `${this.method} ${this.path} HTTP/1.1\n`
    ret += headersToString(this.headers) + '\n\n'
    if (this.data) {
      ret += JSON.stringify(this.data)
    }
    return ret
  }
}

/**
 * Represents a HTTP response message.
 * @final
 */
class Response {
  /**
   * @param {number} status The response code.
   * @param {!Object<string>} headers The response headers. All header names
   *     will be converted to lowercase strings for consistent lookups.
   * @param {string} body The response body.
   */
  constructor(status, headers, body) {
    this.status = /** number */ status
    this.body = /** string */ body
    this.headers = /** !Map<string, string>*/ new Map()
    for (let header in headers) {
      this.headers.set(header.toLowerCase(), headers[header])
    }
  }

  /** @override */
  toString() {
    let ret = `HTTP/1.1 ${this.status}\n${headersToString(this.headers)}\n\n`
    if (this.body) {
      ret += this.body
    }
    return ret
  }
}

/** @enum {!Function} */
const Atom = {
  GET_ATTRIBUTE: getAttribute,
  IS_DISPLAYED: isDisplayed,
  FIND_ELEMENTS: findElements,
}

const LOG = logging.getLogger('webdriver.http')

function post(path) {
  return resource('POST', path)
}
function del(path) {
  return resource('DELETE', path)
}
function get(path) {
  return resource('GET', path)
}
function resource(method, path) {
  return { method: method, path: path }
}

/** @typedef {{method: string, path: string}} */
var CommandSpec // eslint-disable-line

/** @typedef {function(!cmd.Command): !cmd.Command} */
var CommandTransformer // eslint-disable-line

class InternalTypeError extends TypeError {}

/**
 * @param {!cmd.Command} command The initial command.
 * @param {Atom} atom The name of the atom to execute.
 * @param params
 * @return {!Command} The transformed command to execute.
 */
function toExecuteAtomCommand(command, atom, ...params) {
  if (typeof atom !== 'function') {
    throw new InternalTypeError('atom is not a function: ' + typeof atom)
  }

  return new cmd.Command(cmd.Name.EXECUTE_SCRIPT)
    .setParameter('sessionId', command.getParameter('sessionId'))
    .setParameter('script', `return (${atom}).apply(null, arguments)`)
    .setParameter(
      'args',
      params.map((param) => command.getParameter(param))
    )
}

/** @const {!Map<string, (CommandSpec|CommandTransformer)>} */
const W3C_COMMAND_MAP = new Map([
  // Session management.
  [cmd.Name.NEW_SESSION, post('/session')],
  [cmd.Name.QUIT, del('/session/:sessionId')],

  // Server status.
  [cmd.Name.GET_SERVER_STATUS, get('/status')],

  // timeouts
  [cmd.Name.GET_TIMEOUT, get('/session/:sessionId/timeouts')],
  [cmd.Name.SET_TIMEOUT, post('/session/:sessionId/timeouts')],

  // Navigation.
  [cmd.Name.GET_CURRENT_URL, get('/session/:sessionId/url')],
  [cmd.Name.GET, post('/session/:sessionId/url')],
  [cmd.Name.GO_BACK, post('/session/:sessionId/back')],
  [cmd.Name.GO_FORWARD, post('/session/:sessionId/forward')],
  [cmd.Name.REFRESH, post('/session/:sessionId/refresh')],

  // Page inspection.
  [cmd.Name.GET_PAGE_SOURCE, get('/session/:sessionId/source')],
  [cmd.Name.GET_TITLE, get('/session/:sessionId/title')],

  // Script execution.
  [cmd.Name.EXECUTE_SCRIPT, post('/session/:sessionId/execute/sync')],
  [cmd.Name.EXECUTE_ASYNC_SCRIPT, post('/session/:sessionId/execute/async')],

  // Frame selection.
  [cmd.Name.SWITCH_TO_FRAME, post('/session/:sessionId/frame')],
  [cmd.Name.SWITCH_TO_FRAME_PARENT, post('/session/:sessionId/frame/parent')],

  // Window management.
  [cmd.Name.GET_CURRENT_WINDOW_HANDLE, get('/session/:sessionId/window')],
  [cmd.Name.CLOSE, del('/session/:sessionId/window')],
  [cmd.Name.SWITCH_TO_WINDOW, post('/session/:sessionId/window')],
  [cmd.Name.SWITCH_TO_NEW_WINDOW, post('/session/:sessionId/window/new')],
  [cmd.Name.GET_WINDOW_HANDLES, get('/session/:sessionId/window/handles')],
  [cmd.Name.GET_WINDOW_RECT, get('/session/:sessionId/window/rect')],
  [cmd.Name.SET_WINDOW_RECT, post('/session/:sessionId/window/rect')],
  [cmd.Name.MAXIMIZE_WINDOW, post('/session/:sessionId/window/maximize')],
  [cmd.Name.MINIMIZE_WINDOW, post('/session/:sessionId/window/minimize')],
  [cmd.Name.FULLSCREEN_WINDOW, post('/session/:sessionId/window/fullscreen')],

  // Actions.
  [cmd.Name.ACTIONS, post('/session/:sessionId/actions')],
  [cmd.Name.CLEAR_ACTIONS, del('/session/:sessionId/actions')],
  [cmd.Name.PRINT_PAGE, post('/session/:sessionId/print')],

  // Locating elements.
  [cmd.Name.GET_ACTIVE_ELEMENT, get('/session/:sessionId/element/active')],
  [cmd.Name.FIND_ELEMENT, post('/session/:sessionId/element')],
  [cmd.Name.FIND_ELEMENTS, post('/session/:sessionId/elements')],
  [
    cmd.Name.FIND_ELEMENTS_RELATIVE,
    (cmd) => {
      return toExecuteAtomCommand(cmd, Atom.FIND_ELEMENTS, 'args')
    },
  ],
  [
    cmd.Name.FIND_CHILD_ELEMENT,
    post('/session/:sessionId/element/:id/element'),
  ],
  [
    cmd.Name.FIND_CHILD_ELEMENTS,
    post('/session/:sessionId/element/:id/elements'),
  ],
  // Element interaction.
  [cmd.Name.GET_ELEMENT_TAG_NAME, get('/session/:sessionId/element/:id/name')],
  [
    cmd.Name.GET_DOM_ATTRIBUTE,
    get('/session/:sessionId/element/:id/attribute/:name'),
  ],
  [
    cmd.Name.GET_ELEMENT_ATTRIBUTE,
    (cmd) => {
      return toExecuteAtomCommand(cmd, Atom.GET_ATTRIBUTE, 'id', 'name')
    },
  ],
  [
    cmd.Name.GET_ELEMENT_PROPERTY,
    get('/session/:sessionId/element/:id/property/:name'),
  ],
  [
    cmd.Name.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
    get('/session/:sessionId/element/:id/css/:propertyName'),
  ],
  [cmd.Name.GET_ELEMENT_RECT, get('/session/:sessionId/element/:id/rect')],
  [cmd.Name.CLEAR_ELEMENT, post('/session/:sessionId/element/:id/clear')],
  [cmd.Name.CLICK_ELEMENT, post('/session/:sessionId/element/:id/click')],
  [
    cmd.Name.SEND_KEYS_TO_ELEMENT,
    post('/session/:sessionId/element/:id/value'),
  ],
  [cmd.Name.GET_ELEMENT_TEXT, get('/session/:sessionId/element/:id/text')],
  [
    cmd.Name.GET_COMPUTED_ROLE,
    get('/session/:sessionId/element/:id/computedrole'),
  ],
  [
    cmd.Name.GET_COMPUTED_LABEL,
    get('/session/:sessionId/element/:id/computedlabel'),
  ],
  [cmd.Name.IS_ELEMENT_ENABLED, get('/session/:sessionId/element/:id/enabled')],
  [
    cmd.Name.IS_ELEMENT_SELECTED,
    get('/session/:sessionId/element/:id/selected'),
  ],

  [
    cmd.Name.IS_ELEMENT_DISPLAYED,
    (cmd) => {
      return toExecuteAtomCommand(cmd, Atom.IS_DISPLAYED, 'id')
    },
  ],

  // Cookie management.
  [cmd.Name.GET_ALL_COOKIES, get('/session/:sessionId/cookie')],
  [cmd.Name.ADD_COOKIE, post('/session/:sessionId/cookie')],
  [cmd.Name.DELETE_ALL_COOKIES, del('/session/:sessionId/cookie')],
  [cmd.Name.GET_COOKIE, get('/session/:sessionId/cookie/:name')],
  [cmd.Name.DELETE_COOKIE, del('/session/:sessionId/cookie/:name')],

  // Alert management.
  [cmd.Name.ACCEPT_ALERT, post('/session/:sessionId/alert/accept')],
  [cmd.Name.DISMISS_ALERT, post('/session/:sessionId/alert/dismiss')],
  [cmd.Name.GET_ALERT_TEXT, get('/session/:sessionId/alert/text')],
  [cmd.Name.SET_ALERT_TEXT, post('/session/:sessionId/alert/text')],

  // Screenshots.
  [cmd.Name.SCREENSHOT, get('/session/:sessionId/screenshot')],
  [
    cmd.Name.TAKE_ELEMENT_SCREENSHOT,
    get('/session/:sessionId/element/:id/screenshot'),
  ],

  // Shadow Root
  [cmd.Name.GET_SHADOW_ROOT, get('/session/:sessionId/element/:id/shadow')],
  [
    cmd.Name.FIND_ELEMENT_FROM_SHADOWROOT,
    post('/session/:sessionId/shadow/:id/element'),
  ],
  [
    cmd.Name.FIND_ELEMENTS_FROM_SHADOWROOT,
    post('/session/:sessionId/shadow/:id/elements'),
  ],
  // Log extensions.
  [cmd.Name.GET_LOG, post('/session/:sessionId/se/log')],
  [cmd.Name.GET_AVAILABLE_LOG_TYPES, get('/session/:sessionId/se/log/types')],

  // Server Extensions
  [cmd.Name.UPLOAD_FILE, post('/session/:sessionId/se/file')],

  // Virtual Authenticator
  [
    cmd.Name.ADD_VIRTUAL_AUTHENTICATOR,
    post('/session/:sessionId/webauthn/authenticator'),
  ],
  [
    cmd.Name.REMOVE_VIRTUAL_AUTHENTICATOR,
    del('/session/:sessionId/webauthn/authenticator/:authenticatorId'),
  ],
  [
    cmd.Name.ADD_CREDENTIAL,
    post(
      '/session/:sessionId/webauthn/authenticator/:authenticatorId/credential'
    ),
  ],
  [
    cmd.Name.GET_CREDENTIALS,
    get(
      '/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials'
    ),
  ],
  [
    cmd.Name.REMOVE_CREDENTIAL,
    del(
      '/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials/:credentialId'
    ),
  ],
  [
    cmd.Name.REMOVE_ALL_CREDENTIALS,
    del(
      '/session/:sessionId/webauthn/authenticator/:authenticatorId/credentials'
    ),
  ],
  [
    cmd.Name.SET_USER_VERIFIED,
    post('/session/:sessionId/webauthn/authenticator/:authenticatorId/uv'),
  ],
])

/**
 * Handles sending HTTP messages to a remote end.
 *
 * @interface
 */
class Client {
  /**
   * Sends a request to the server. The client will automatically follow any
   * redirects returned by the server, fulfilling the returned promise with the
   * final response.
   *
   * @param {!Request} httpRequest The request to send.
   * @return {!Promise<Response>} A promise that will be fulfilled with the
   *     server's response.
   */
  send(httpRequest) {} // eslint-disable-line
}

/**
 * @param {Map<string, CommandSpec>} customCommands
 *     A map of custom command definitions.
 * @param {!cmd.Command} command The command to resolve.
 * @return {!Request} A promise that will resolve with the
 *     command to execute.
 */
function buildRequest(customCommands, command) {
  LOG.finest(() => `Translating command: ${command.getName()}`)
  let spec = customCommands && customCommands.get(command.getName())
  if (spec) {
    return toHttpRequest(spec)
  }

  spec = W3C_COMMAND_MAP.get(command.getName())
  if (typeof spec === 'function') {
    LOG.finest(() => `Transforming command for W3C: ${command.getName()}`)
    let newCommand = spec(command)
    return buildRequest(customCommands, newCommand)
  } else if (spec) {
    return toHttpRequest(spec)
  }
  throw new error.UnknownCommandError(
    'Unrecognized command: ' + command.getName()
  )

  /**
   * @param {CommandSpec} resource
   * @return {!Request}
   */
  function toHttpRequest(resource) {
    LOG.finest(() => `Building HTTP request: ${JSON.stringify(resource)}`)
    let parameters = command.getParameters()
    let path = buildPath(resource.path, parameters)
    return new Request(resource.method, path, parameters)
  }
}

const CLIENTS =
  /** !WeakMap<!Executor, !(Client|IThenable<!Client>)> */ new WeakMap()

/**
 * A command executor that communicates with the server using JSON over HTTP.
 *
 * By default, each instance of this class will use the legacy wire protocol
 * from [Selenium project][json]. The executor will automatically switch to the
 * [W3C wire protocol][w3c] if the remote end returns a compliant response to
 * a new session command.
 *
 * [json]: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol
 * [w3c]: https://w3c.github.io/webdriver/webdriver-spec.html
 *
 * @implements {cmd.Executor}
 */
class Executor {
  /**
   * @param {!(Client|IThenable<!Client>)} client The client to use for sending
   *     requests to the server, or a promise-like object that will resolve
   *     to the client.
   */
  constructor(client) {
    CLIENTS.set(this, client)

    /** @private {Map<string, CommandSpec>} */
    this.customCommands_ = null

    /** @private {!logging.Logger} */
    this.log_ = logging.getLogger('webdriver.http.Executor')
  }

  /**
   * Defines a new command for use with this executor. When a command is sent,
   * the {@code path} will be preprocessed using the command's parameters; any
   * path segments prefixed with ":" will be replaced by the parameter of the
   * same name. For example, given "/person/:name" and the parameters
   * "{name: 'Bob'}", the final command path will be "/person/Bob".
   *
   * @param {string} name The command name.
   * @param {string} method The HTTP method to use when sending this command.
   * @param {string} path The path to send the command to, relative to
   *     the WebDriver server's command root and of the form
   *     "/path/:variable/segment".
   */
  defineCommand(name, method, path) {
    if (!this.customCommands_) {
      this.customCommands_ = new Map()
    }
    this.customCommands_.set(name, { method, path })
  }

  /** @override */
  async execute(command) {
    let request = buildRequest(this.customCommands_, command)
    this.log_.finer(() => `>>> ${request.method} ${request.path}`)

    let client = CLIENTS.get(this)
    if (promise.isPromise(client)) {
      client = await client
      CLIENTS.set(this, client)
    }

    let response = await client.send(request)
    this.log_.finer(() => `>>>\n${request}\n<<<\n${response}`)

    let httpResponse = /** @type {!Response} */ (response)

    let { isW3C, value } = parseHttpResponse(command, httpResponse)

    if (command.getName() === cmd.Name.NEW_SESSION) {
      if (!value || !value.sessionId) {
        throw new error.WebDriverError(
          `Unable to parse new session response: ${response.body}`
        )
      }

      // The remote end is a W3C compliant server if there is no `status`
      // field in the response.
      if (command.getName() === cmd.Name.NEW_SESSION) {
        this.w3c = this.w3c || isW3C
      }

      // No implementations use the `capabilities` key yet...
      let capabilities = value.capabilities || value.value
      return new Session(
        /** @type {{sessionId: string}} */ (value).sessionId,
        capabilities
      )
    }

    return typeof value === 'undefined' ? null : value
  }
}

/**
 * @param {string} str .
 * @return {?} .
 */
function tryParse(str) {
  try {
    return JSON.parse(str)
  } catch (ignored) {
    // Do nothing.
  }
}

/**
 * Callback used to parse {@link Response} objects from a
 * {@link HttpClient}.
 *
 * @param {!cmd.Command} command The command the response is for.
 * @param {!Response} httpResponse The HTTP response to parse.
 * @return {{isW3C: boolean, value: ?}} An object describing the parsed
 *     response. This object will have two fields: `isW3C` indicates whether
 *     the response looks like it came from a remote end that conforms with the
 *     W3C WebDriver spec, and `value`, the actual response value.
 * @throws {WebDriverError} If the HTTP response is an error.
 */
function parseHttpResponse(command, httpResponse) {
  if (httpResponse.status < 200) {
    // This should never happen, but throw the raw response so users report it.
    throw new error.WebDriverError(`Unexpected HTTP response:\n${httpResponse}`)
  }

  let parsed = tryParse(httpResponse.body)

  if (parsed && typeof parsed === 'object') {
    let value = parsed.value
    let isW3C = isObject(value) && typeof parsed.status === 'undefined'

    if (!isW3C) {
      error.checkLegacyResponse(parsed)

      // Adjust legacy new session responses to look like W3C to simplify
      // later processing.
      if (command.getName() === cmd.Name.NEW_SESSION) {
        value = parsed
      }
    } else if (httpResponse.status > 399) {
      error.throwDecodedError(value)
    }

    return { isW3C, value }
  }

  if (parsed !== undefined) {
    return { isW3C: false, value: parsed }
  }

  let value = httpResponse.body.replace(/\r\n/g, '\n')

  // 404 represents an unknown command; anything else > 399 is a generic unknown
  // error.
  if (httpResponse.status === 404) {
    throw new error.UnsupportedOperationError(command.getName() + ': ' + value)
  } else if (httpResponse.status >= 400) {
    throw new error.WebDriverError(value)
  }

  return { isW3C: false, value: value || null }
}

/**
 * Builds a fully qualified path using the given set of command parameters. Each
 * path segment prefixed with ':' will be replaced by the value of the
 * corresponding parameter. All parameters spliced into the path will be
 * removed from the parameter map.
 * @param {string} path The original resource path.
 * @param {!Object<*>} parameters The parameters object to splice into the path.
 * @return {string} The modified path.
 */
function buildPath(path, parameters) {
  let pathParameters = path.match(/\/:(\w+)\b/g)
  if (pathParameters) {
    for (let i = 0; i < pathParameters.length; ++i) {
      let key = pathParameters[i].substring(2) // Trim the /:
      if (key in parameters) {
        let value = parameters[key]
        if (webElement.isId(value)) {
          // When inserting a WebElement into the URL, only use its ID value,
          // not the full JSON.
          value = webElement.extractId(value)
        }
        path = path.replace(pathParameters[i], '/' + value)
        delete parameters[key]
      } else {
        throw new error.InvalidArgumentError(
          'Missing required parameter: ' + key
        )
      }
    }
  }
  return path
}

// PUBLIC API

module.exports = {
  Executor,
  Client,
  Request,
  Response,
  // Exported for testing.
  buildPath,
}
