/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.
 */

'use strict'

const BaseOperation = require('./base_operation')
const messages = require('./messages')
const names = require('./names')
const CREATE_PARAMS = ['relpath', 'operation', 'action']

class Routes extends BaseOperation {
  routeMgmtApiPath (path) {
    return `web/whisk.system/apimgmt/${path}.http`
  }

  get (options) {
    options = options || {}
    options.basepath = this.basepath(options)

    return this.list(this.qs(options, ['basepath']))
  }

  list (options) {
    options = options || {}
    if (this.hasBasepath(options)) {
      options.basepath = this.calculateBasepath(options)
    }

    const qs = this.qs(options, ['relpath', 'basepath', 'operation', 'limit', 'skip'])
    return this.client.request('GET', this.routeMgmtApiPath('getApi'), { qs })
  }

  qs (options, names) {
    const result = super.qs(options, names)

    if (this.hasAccessToken()) {
      result.accesstoken = this.client.options.apigwToken
      result.spaceguid = this.client.options.apigwSpaceGuid
    }

    return result
  }

  hasBasepath (options) {
    return !!(options.name || options.basepath)
  }

  basepath (options) {
    if (!this.hasBasepath(options)) {
      throw new Error(messages.MISSING_BASEPATH_ERROR)
    }

    return this.calculateBasepath(options)
  }

  calculateBasepath (options) {
    if (options.name && options.basepath) {
      throw new Error(messages.INVALID_BASEPATH_ERROR)
    }

    return options.basepath || options.name
  }

  missingBasepath (options) {
    return !(options.name || options.basepath)
  }

  delete (options) {
    options = options || {}
    options.basepath = this.basepath(options)

    const qs = this.qs(options, ['relpath', 'basepath', 'operation'])
    qs.force = true
    return this.client.request('DELETE', this.routeMgmtApiPath('deleteApi'), { qs })
  }

  create (options) {
    const body = this.createBody(options || {})
    const qs = this.qs(options, ['responsetype'])
    return this.client.request('POST', this.routeMgmtApiPath('createApi'), { body, qs })
  }

  createBody (options) {
    if (options.swagger) {
      return { apidoc: { namespace: '_', swagger: options.swagger } }
    }

    const missing = CREATE_PARAMS.filter(param => !(options || {}).hasOwnProperty(param))

    if (missing.length) {
      throw new Error(`Missing mandatory parameters: ${missing.join(', ')}`)
    }

    return this.routeSwaggerDefinition(options)
  }

  routeSwaggerDefinition (params) {
    const apidoc = {
      namespace: '_',
      gatewayBasePath: this.routeBasepath(params),
      gatewayPath: params.relpath,
      gatewayMethod: params.operation,
      id: `API:_:${this.routeBasepath(params)}`,
      action: this.routeSwaggerAction(params)
    }

    const pathParameters = this.parsePathParameters(params.relpath)

    if (pathParameters.length) {
      apidoc.pathParameters = pathParameters.map(this.createPathParameter)
    }

    if (params.name) {
      apidoc.apiName = params.name
    }

    return { apidoc }
  }

  routeSwaggerAction (params) {
    const id = names.parseId(params.action)
    let namespace = decodeURIComponent(this.namespace(params))
    if (params.action.startsWith('/')) {
      namespace = names.parseNamespace(params.action)
    }

    const body = {
      name: id,
      namespace: namespace,
      backendMethod: `GET`,
      backendUrl: this.actionUrlPath(id, namespace),
      authkey: this.client.options.apiKey
    }

    if (params.secure_key) {
      body.secureKey = params.secure_key
    }

    return body
  }

  routeBasepath (params) {
    return params.basepath || '/'
  }

  actionUrlPath (id, namespace) {
    // web action path must contain package identifier. uses default for
    // non-explicit package.
    if (!id.includes('/')) {
      id = `default/${id}`
    }

    return this.client.pathUrl(`web/${namespace}/${id}.http`)
  }

  hasAccessToken () {
    return !!this.client.options.apigwToken
  }

  // return list of path parameters from paths
  // e.g. /book/{id}
  // Multiple parameters are supported.
  parsePathParameters (path) {
    const regex = /{([^}]+)\}/g
    const findAllParams = p => {
      const ids = []
      let id = regex.exec(p)
      while (id) {
        ids.push(id[1])
        id = regex.exec(p)
      }
      return ids
    }

    return path.split('/')
      .map(findAllParams)
      .reduce((sum, el) => sum.concat(el), [])
  }

  createPathParameter (name) {
    return {
      name: name,
      in: 'path',
      description: `Default description for '${name}'`,
      required: true,
      type: 'string'
    }
  }
}

module.exports = Routes
