// 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('node: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 log_ = logging.getLogger(`${logging.Type.DRIVER}.http`)

const getAttribute = requireAtom('get-attribute.js', '//javascript/selenium-webdriver/lib/atoms:get-attribute.js')
const isDisplayed = requireAtom('is-displayed.js', '//javascript/selenium-webdriver/lib/atoms:is-displayed.js')
const findElements = requireAtom('find-elements.js', '//javascript/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(':', '/')
      log_.log(`../../../bazel-bin/${file}`)
      return require(path.resolve(`../../../bazel-bin/${file}`))
    } catch (ex2) {
      log_.severe(ex2)
      throw new Error(
        `Failed to import atoms module ${module}. If running in dev mode, you` +
          ` need to run \`bazel build ${bazelTarget}\` from the project` +
          `root: ${ex}`,
        { cause: ex2 },
      )
    }
  }
}

/**
 * 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,
}

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

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

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, name, ...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', `/* ${name} */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, 'findElements', '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, 'getAttribute', '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, 'isDisplayed', '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')],

  [cmd.Name.GET_DOWNLOADABLE_FILES, get('/session/:sessionId/se/files')],
  [cmd.Name.DOWNLOAD_FILE, post(`/session/:sessionId/se/files`)],
  [cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)],

  [cmd.Name.FIRE_SESSION_EVENT, post(`/session/:sessionId/se/event`)],

  // Federated Credential Management Command
  [cmd.Name.CANCEL_DIALOG, post(`/session/:sessionId/fedcm/canceldialog`)],
  [cmd.Name.SELECT_ACCOUNT, post(`/session/:sessionId/fedcm/selectaccount`)],
  [cmd.Name.GET_FEDCM_TITLE, get(`/session/:sessionId/fedcm/gettitle`)],
  [cmd.Name.GET_FEDCM_DIALOG_TYPE, get('/session/:sessionId/fedcm/getdialogtype')],
  [cmd.Name.SET_DELAY_ENABLED, post(`/session/:sessionId/fedcm/setdelayenabled`)],
  [cmd.Name.RESET_COOLDOWN, post(`/session/:sessionId/fedcm/resetcooldown`)],
  [cmd.Name.CLICK_DIALOG_BUTTON, post(`/session/:sessionId/fedcm/clickdialogbutton`)],
  [cmd.Name.GET_ACCOUNTS, get(`/session/:sessionId/fedcm/accountlist`)],
])

/**
 * 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) {}
}

/**
 * @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(`${logging.Type.DRIVER}.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)
    /*eslint no-unused-vars: "off"*/
  } 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,
}
