'use strict'

const messages = require('./messages')
const BaseOperationError = require('./base_operation_error')
const rp = require('request-promise')
const url = require('url')

class BaseOperation {
  constructor (options) {
    this.options = this.parse_options(options || {})
  }

  parse_options (options) {
    const api_key = options.api_key || process.env['__OW_APIKEY']
    const namespace = options.namespace || process.env['__OW_NAMESPACE']
    const ignore_certs = options.ignore_certs
    // if apihost is available, parse this into full API url
    const api = options.api ||
      this.url_from_apihost(options.apihost || process.env['__OW_APIHOST'])

    if (!api_key) {
      throw new Error(`${messages.INVALID_OPTIONS_ERROR} Missing api_key parameter.`)
    } else if (!api) {
      throw new Error(`${messages.INVALID_OPTIONS_ERROR} Missing either api or apihost parameters.`)
    }

    return {api_key, namespace, api, ignore_certs}
  }

  url_from_apihost (apihost) {
    if (!apihost) return apihost

    const is_http = apihost.includes(':') && !apihost.includes(':443')
    const protocol = is_http ? 'http' : 'https'
    return `${protocol}://${apihost}/api/v1/`
  }

  request (options) {
    return rp(options).catch(err => this.handle_errors(err))
  }

  params (method, path) {
    return {
      json: true,
      method: method,
      url: this.path_url(path),
      rejectUnauthorized: !this.options.ignore_certs,
      headers: {
        Authorization: this.auth_header()
      }
    }
  }

  path_url (url_path) {
    const endpoint = this.api_url()
    endpoint.pathname = url.resolve(endpoint.pathname, url_path)
    return url.format(endpoint)
  }

  api_url () {
    return url.parse(
      this.options.api.endsWith('/') ? this.options.api : this.options.api + '/'
    )
  }

  namespace (options) {
    if (options && typeof options.namespace === 'string') {
      return encodeURIComponent(options.namespace)
    } else if (typeof this.options.namespace === 'string') {
      return encodeURIComponent(this.options.namespace)
    }

    throw new Error(messages.MISSING_NAMESPACE_ERROR)
  }

  qs (options, names) {
    return names.filter(name => options.hasOwnProperty(name))
      .reduce((previous, name) => {
        previous[name] = options[name]
        return previous
      }, {})
  }

  auth_header () {
    const api_key_base64 = new Buffer(this.options.api_key).toString('base64')
    return `Basic ${api_key_base64}`
  }

  handle_errors (reason) {
    if (reason.hasOwnProperty('statusCode')) {
      switch (reason.statusCode) {
        case 401:
        case 403:
          throw new Error(messages.INVALID_AUTH_ERROR)
        case 404:
          throw new Error(messages.MISSING_URL_ERROR)
        case 408:
          throw new Error(messages.INVOKE_TIMEOUT_ERROR)
        case 409:
          throw new Error(messages.CREATE_CONFLICT_ERROR)
        default:
          let error = 'Missing error message.'
          if (reason.error) {
            if (reason.error.response && reason.error.response.result && reason.error.response.result.error) {
              error = reason.error.response.result.error
            }
            throw new BaseOperationError(`${messages.API_SYSTEM_ERROR} ${error}`, reason.error)
          } else {
            throw new Error(`${messages.API_SYSTEM_ERROR} ${error}`)
          }
      }
    }

    throw new Error(`Error encountered calling OpenWhisk: ${reason.message}`)
  }
}

module.exports = BaseOperation
