--
-- 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 backendOverride = os.getenv("BACKEND_HOST")

local _M = {}

local 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

--- Set upstream based on the backendUrl
function _M.setRoute(backendUrl, gatewayPath)
  _M.setRouteWithOverride(backendUrl, gatewayPath, backendOverride)
end

function _M.setRouteWithOverride(backendUrl, gatewayPath, override)
  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(_M.getUriPath(u.path))
  end
  ngx.var.backendUrl = backendUrl

  -- if there is a backend override then use that instead of actual backend from swagger
  if override ~= nil then
    local bou = url.parse(override)
    u.scheme = bou.scheme
    u:setAuthority(bou.authority)

    -- update the copy in ngx var also to match upstream
    local bu = url.parse(backendUrl)
    bu.scheme = bou.scheme
    bu:setAuthority(bou.authority)
    ngx.var.backendUrl = bu:build()
  end
  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(_M.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 _M.getUriPath(backendPath)
  local gatewayPath = ngx.unescape_uri(ngx.var.gatewayPath)
  gatewayPath = gatewayPath:gsub('-', '%%-')
  local tenant = ngx.var.tenant:gsub('-', '%%-')
  local uri = string.gsub(ngx.var.request_uri, '?.*', '')
  uri = uri:gsub('/api/' .. tenant, '')
  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

return _M
