--
-- 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 backendRouting
-- Used to set the backend Url either statically or dynamically

local url = require "url"
local utils = require "lib/utils"
local request = require "lib/request"
local logger = require "lib/logger"

local _M = {}

--- Set upstream based on the backendUrl
function _M.setRoute(backendUrl, gatewayPath)
  local u = url.parse(backendUrl)
  if u.scheme == nil then
    u = url.parse(utils.concatStrings({'http://', backendUrl}))
  end
  -- pass down gateway path to upstream path if $(request.path) is specified at the end of backendUrl
  if u.path:sub(-15) == '$(request.path)' then
    u.path = utils.concatStrings({u.path:sub(1, -16), u.path:sub(-16, -16) == '/' and '' or '/', gatewayPath})
    ngx.req.set_uri(u.path)
  else
    ngx.req.set_uri(getUriPath(u.path))
  end
  ngx.var.backendUrl = backendUrl
  setUpstream(u)
end

--- Set dynamic route based on the header that is passed in
function _M.setDynamicRoute(obj)
  local whitelist = obj.whitelist
  for k in pairs(whitelist) do
    whitelist[k] = whitelist[k]:lower()
  end
  local header = obj.header ~= nil and obj.header or 'X-Cf-Forwarded-Url'
  local dynamicBackend = ngx.req.get_headers()[header]
  if dynamicBackend ~= nil and dynamicBackend ~= '' then
    local u = url.parse(dynamicBackend)
    if u.scheme == nil or u.scheme == '' then
      u = url.parse(utils.concatStrings({'http://', dynamicBackend}))
    end
    if utils.tableContains(whitelist, u.host) then
      ngx.req.set_uri(getUriPath(u.path))
      -- Split the dynamicBackend url to get the query parameters in the exact order that it was passed in.
      -- Don't use u.query here because it returns the parameters in an unordered lua table.
      local split = {string.match(dynamicBackend, '([^?]*)?(.*)')}
      local qs = split[2]
      if qs ~= nil then
        ngx.req.set_uri_args(qs)
      end
      setUpstream(u)
    else
      request.err(403, 'Dynamic backend host not part of whitelist.')
    end
  else
    logger.info('Header for dynamic routing not found. Defaulting to backendUrl.')
  end
end

function getUriPath(backendPath)
  local gatewayPath = ngx.unescape_uri(ngx.var.gatewayPath)
  gatewayPath = gatewayPath:gsub('-', '%%-')
  local uri = string.gsub(ngx.var.request_uri, '?.*', '')
  local _, j = uri:find(gatewayPath)
  local incomingPath = ((j and uri:sub(j + 1)) or nil)
  -- Check for backendUrl path
  if backendPath == nil or backendPath == '' or backendPath == '/' then
    incomingPath = (incomingPath and incomingPath ~= '') and incomingPath or '/'
    incomingPath = string.sub(incomingPath, 1, 1) == '/' and incomingPath or utils.concatStrings({'/', incomingPath})
    return incomingPath
  else
    return utils.concatStrings({backendPath, incomingPath})
  end
end

function setUpstream(u)
  local upstream = utils.concatStrings({u.scheme, '://', u.host})
  if u.port ~= nil and u.port ~= '' then
    upstream = utils.concatStrings({upstream, ':', u.port})
  end
  ngx.var.upstream = upstream
end

return _M
