--
-- 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.
--

--- @module mapping
-- Process mapping object, turning implementation details into request transformations

local logger = require "lib/logger"
local utils = require "lib/utils"
local cjson = require "cjson"

local _M = {}

local body
local query
local headers
local path

--- Implementation for the mapping policy.
-- @param map The mapping object that contains details about request tranformations
function processMap(map)
  getRequestParams()
  for k, v in pairs(map) do
    if v.action == "insert" then
      insertParam(v)
    elseif v.action == "remove" then
      removeParam(v)
    elseif v.action == "transform" then
      transformParam(v)
    elseif v.action == "default" then
      checkDefault(v)
    else
      logger.err(utils.concatStrings({'Map action not recognized. Skipping... ', v.action}))
    end
  end
  finalize()
end

--- Get request body, params, and headers from incoming requests
function getRequestParams()
  ngx.req.read_body()
  body = ngx.req.get_body_data()
  body = (body and cjson.decode(body)) or {}
  headers = ngx.req.get_headers()
  path = ngx.var.uri
  query = parseUrl(ngx.var.backendUrl)
  local incomingQuery = ngx.req.get_uri_args()
  for k, v in pairs (incomingQuery) do
    query[k] = v
  end
end

--- Insert parameter value to header, body, or query params into request
-- @param m Parameter value to add to request
function insertParam(m)
  local v
  local k = m.to.name
  if m.from.value ~= nil then
    v = m.from.value
  elseif m.from.location == 'header' then
    v = headers[m.from.name]
  elseif m.from.location == 'query' then
    v = query[m.from.name]
  elseif m.from.location == 'body' then
    v = body[m.from.name]
  elseif m.from.location == 'path' then
    v = ngx.ctx[m.from.name]
  end
  -- determine to where
  if m.to.location == 'header' then
    insertHeader(k, v)
  elseif m.to.location == 'query' then
    insertQuery(k, v)
  elseif m.to.location == 'body' then
    insertBody(k, v)
  elseif m.to.location == 'path' then
    insertPath(k,v)
  end
end

--- Remove parameter value to header, body, or query params from request
-- @param m Parameter value to remove from request
function removeParam(m)
  if m.from.location == "header" then
    removeHeader(m.from.name)
  elseif m.from.location == "query" then
    removeQuery(m.from.name)
  elseif m.from.location == "body" then
    removeBody(m.from.name)
  end
end

--- Move parameter value from one location to another in the request
-- @param m Parameter value to move within request
function transformParam(m)
  if m.from.name == '*' then
    transformAllParams(m.from.location, m.to.location)
  else
    insertParam(m)
    removeParam(m)
  end
end

--- Checks if the header has been set, and sets the header to a value if found to be null.
-- @param m Header name and value to be set, if header is null.
function checkDefault(m)
  if m.to.location == "header" and headers[m.to.name] == nil then
    insertHeader(m.to.name, m.from.value)
  elseif m.to.location == "query" and query[m.to.name] == nil then
    insertQuery(m.to.name, m.from.value)
  elseif m.to.location == "body" and body[m.to.name] == nil then
    insertBody(m.to.name, m.from.value)
  end
end

--- Function to handle wildcarding in the transform process.
-- If the value in the from object is '*', this function will pull all values from the incoming request
-- and move them to the location provided in the to object
-- @param s The source object from which we pull all parameters
-- @param d The destination object that we will move all found parameters to.
function transformAllParams(s, d)
  if s == 'query' then
    for k, v in pairs(query) do
      local t = {}
      t.from = {}
      t.from.name = k
      t.from.location = s
      t.to = {}
      t.to.name = k
      t.to.location = d
      insertParam(t)
      removeParam(t)
    end
  elseif s == 'header' then
    for k, v in pairs(headers) do
      local t = {}
      t.from = {}
      t.from.name = k
      t.from.location = s
      t.to = {}
      t.to.name = k
      t.to.location = d
      insertParam(t)
      removeParam(t)
    end
  elseif s == 'body' then
    for k, v in pairs(body) do
      local t = {}
      t.from = {}
      t.from.name = k
      t.from.location = s
      t.to = {}
      t.to.name = k
      t.to.location = d
      insertParam(t)
      removeParam(t)
    end
  elseif s == 'path' then
    for k, v in pairs(path) do
      local t = {}
      t.from = {}
      t.from.name = k
      t.from.location = s
      t.to = {}
      t.to.name = k
      t.to.location = d
      insertParam(t)
      removeParam(t)
    end
  end
end

function finalize()
  if next(body) ~= nil then
    local bodyJson = cjson.encode(body)
    ngx.req.set_body_data(bodyJson)
  end
  ngx.req.set_uri_args(query)
end

function insertHeader(k, v)
  ngx.req.set_header(k, v)
  headers[k] = v
end

function insertQuery(k, v)
  query[k] = v
end

function insertBody(k, v)
  body[k] = v
end

function insertPath(k, v)
  v = ngx.unescape_uri(v)
  path = path:gsub(utils.concatStrings({"%{", k ,"%}"}), v)
  ngx.req.set_uri(path)
end

function removeHeader(k)
  ngx.req.clear_header(k)
end

function removeQuery(k)
  query[k] = nil
end

function removeBody(k)
  body[k] = nil
end

function parseUrl(url)
  local map = {}
  for k,v in url:gmatch('([^&=?]+)=([^&=?]+)') do
    map[ k ] = decodeQuery(v)
  end
  return map
end

function decodeQuery(param)
  local decoded = param:gsub('+', ' '):gsub('%%(%x%x)',
    function(hex) return string.char(tonumber(hex, 16)) end)
  return decoded
end

_M.processMap = processMap

return _M
