--
-- 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 Routing
-- Used to dynamically handle nginx routing based on an object containing implementation details

local cjson = require "cjson"
if (cjson.decode_array_with_array_mt ~= nil) then
  cjson.decode_array_with_array_mt(true)
end
local url = require "url"
local utils = require "lib/utils"
local request = require "lib/request"
local logger = require "lib/logger"
-- load policies
local security = require "policies/security"
local mapping = require "policies/mapping"
local rateLimit = require "policies/rateLimit"
local backendRouting = require "policies/backendRouting"
local cors = require "cors"
local OPTIMIZE = os.getenv("OPTIMIZE")

if OPTIMIZE ~= nil then
  OPTIMIZE = tonumber(OPTIMIZE)
else
  OPTIMIZE = 0
end

local SNAPSHOTTING = os.getenv('SNAPSHOTTING')

local _M = {}

--- Main function that handles parsing of invocation details and carries out implementation
function _M.processCall(dataStore)
  -- Get request headers
  local requestHeaders = ngx.req.get_headers()
  -- Get resource object from redis
  local tenantId = ngx.var.tenant

  if SNAPSHOTTING == 'true' then
    dataStore:setSnapshotId(tenantId)
  end
  local gatewayPath = ngx.var.gatewayPath
  local i, j = ngx.var.request_uri:find("/api/([^/]+)")
  ngx.var.analyticsUri = ngx.var.request_uri:sub(j+1)
  if ngx.req.get_headers()["x-debug-mode"] == "true" then
    setRequestLogs()
  end
  local redisKey = _M.findResource(dataStore, tenantId, gatewayPath)
  if redisKey == nil then
    request.err(404, 'Not found.')
  end
  local resource = dataStore:getResource(redisKey, "resources")
  if resource == nil then
    request.err(404, 'Snapshot not found.')
  end
  local obj = cjson.decode(resource)

  cors.processCall(obj)
  ngx.var.tenantNamespace = obj.tenantNamespace
  ngx.var.tenantInstance = obj.tenantInstance
  ngx.var.apiId = obj.apiId
  for verb, opFields in pairs(obj.operations) do
    if string.upper(verb) == ngx.req.get_method() then
      -- Check if auth is required
      local key
      if (opFields.security) then
        for _, sec in ipairs(opFields.security) do
          local result = security.process(dataStore, sec)
          if key == nil and sec.type ~= "oauth2" then
            key = result -- use key from either apiKey or clientSecret security policy
          end
        end
      end
      -- Set backend method
      if opFields.backendMethod ~= nil then
        setVerb(opFields.backendMethod)
      end
      -- Set backend upstream and uri
      backendRouting.setRoute(opFields.backendUrl, gatewayPath)
      -- Set gateway url as request header
      local requestScheme = requestHeaders["X-Forwarded-Proto"]
      if requestScheme == nil or requestScheme == "" then
        requestScheme = ngx.var.scheme
      end
      local requestHost = requestHeaders["X-Forwarded-Host"]
      if requestHost == nil or requestHost == "" then
        requestHost = ngx.var.host
      end
      local requestUrl = utils.concatStrings({requestScheme, "://", requestHost})
      local prefix = requestHeaders["X-Forwarded-Prefix"]
      if prefix ~= nil and prefix ~= "" then
        requestUrl = utils.concatStrings({requestUrl, prefix})
      end
      local requestUri = requestHeaders["X-Forwarded-Uri"]
      if requestUri == nil or requestUri == "" then
        requestUri = ngx.var.request_uri
      end
      ngx.req.set_header("X-Forwarded-Url", utils.concatStrings({requestUrl, requestUri}))
      -- Parse policies
      if opFields.policies ~= nil then
        parsePolicies(dataStore, opFields.policies, key)
      end
      -- Log updated request headers/body info to access logs
      if requestHeaders["x-debug-mode"] == "true" then
        setRequestLogs()
      end
      dataStore:close()
      return nil
    end
  end
  request.err(404, 'Whoops. Verb not supported.')
end

--- Find the correct redis key based on the path that's passed in
-- @param dataStore the datastore object
-- @param tenant tenantId
-- @param path path to look for
function _M.findResource(dataStore, tenant, path)
  -- Check for exact match
  local redisKey = utils.concatStrings({"resources:", tenant, ":", path})
  local cfRedisKey
  local cfUrl = ngx.req.get_headers()["x-cf-forwarded-url"]
  if cfUrl ~= nil and cfUrl ~= "" then
    local u = url.parse(cfUrl)
    cfRedisKey = utils.concatStrings({"resources:", tenant, ":", path, u.path})
    ngx.var.analyticsUri = (u.path == "") and "/" or u.path
    if next(u.query) ~= nil then
      ngx.var.analyticsUri = utils.concatStrings({ngx.var.analyticsUri, '?', u.query})
    end
  end

  local result
  if OPTIMIZE > 0 then
    result = dataStore:optimizedLookup(tenant, path)
  end
  if result ~= nil then
    ngx.var.gatewayPath = result:gsub(utils.concatStrings({'resources:', tenant, ':'}), '')
    return result
  end

  local resourceKeys = dataStore:getAllResources(tenant)
  local result = _M.slowLookup(resourceKeys, tenant, path, redisKey, cfRedisKey)

  if OPTIMIZE > 0 and result ~= nil then
    dataStore:optimizeLookup(tenant, result, path)
  end

  return result
end

--- Perform a linear lookup of the api based on the apis in a tenant
-- @param resourceKeys all of the resources under a given tenant
-- @param tenant the tenant we are looking up for
-- @param path the path used to call the api gateway
-- @param redisKey a guess for a redis key based on the tenant id and path
-- @param cfRedisKey a redis key that will exist if cloud foundry routing logic is used
function _M.slowLookup(resourceKeys, tenant, path, redisKey, cfRedisKey)
  for _, key in pairs(resourceKeys) do
    if key == redisKey or key == cfRedisKey then
      local res = {string.match(key, "([^:]+):([^:]+):([^:]+)")}
      ngx.var.gatewayPath = res[3]
      return key
    end
  end
  if cfUrl ~= nil and cfUrl ~= "" then
    return nil
  end
  -- Construct a table of redisKeys based on number of slashes in the path
  local keyTable = {}
  for i, key in pairs(resourceKeys) do
    local _, count = string.gsub(key, "/", "")
    -- handle cases where resource path is "/"
    if count == 1 and string.sub(key, -1) == "/" then
      count = count - 1
    end
    count = tostring(count)
    if keyTable[count] == nil then
      keyTable[count] = {}
    end
    table.insert(keyTable[count], key)
  end
  -- Check for proxy or path parameter matching
  local _, count = string.gsub(redisKey, "/", "")
  for i = count, 0, -1 do
    local countString = tostring(i)
    if keyTable[countString] ~= nil then
      for _, key in pairs(keyTable[countString]) do
        -- Check for exact match or path parameter match
        if key == redisKey or key == utils.concatStrings({redisKey, "/"}) or _M.pathParamMatch(key, redisKey) == true then
          local res = {string.match(key, "([^:]+):([^:]+):([^:]+)")}
          ngx.var.gatewayPath = res[3]
          return key
        end
      end
    end
    -- substring redisKey upto last "/"
    local index = redisKey:match("^.*()/")
    if index == nil then
      return nil
    end
    redisKey = string.sub(redisKey, 1, index - 1)
  end
  return nil

end

--- Check redis if resourceKey matches path parameters
-- @param key key that may have path parameter variables
-- @param resourceKey redis resourceKey to check if it matches path parameter
function _M.pathParamMatch(key, resourceKey)
  local pathParamVars = {}
  for w in string.gmatch(key, "({%w+})") do
    w = string.sub(w, 2, string.len(w) - 1)
    pathParamVars[#pathParamVars + 1] = w
  end
  if next(pathParamVars) ~= nil then
    local pathPattern, count = string.gsub(key, "%{(%w*)%}", "([^:]+)")
    pathPattern = string.gsub(pathPattern, "%-", "%%-")
    local obj = {string.match(resourceKey, pathPattern)}
    if (#obj == count) then
      for i, v in pairs(obj) do
        ngx.ctx[pathParamVars[i]] = v
      end
      return true
    end
  end
  return false
end

--- Function to read the list of policies and send implementation to the correct backend
-- @param red redis client instance
-- @param obj List of policies containing a type and value field. This function reads the type field and routes it appropriately.
-- @param apiKey optional subscription api key
function parsePolicies(dataStore, obj, apiKey)
  for k, v in pairs (obj) do
    if v.type == 'reqMapping' then
      mapping.processMap(v.value)
    elseif v.type == 'rateLimit' then
      rateLimit.limit(dataStore, v.value, apiKey)
    elseif v.type == 'backendRouting' then
      backendRouting.setDynamicRoute(v.value)
    end
  end
end

--- Given a verb, transforms the backend request to use that method
-- @param v Verb to set on the backend request
function setVerb(v)
  local allowedVerbs = {'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'}
  local verb = string.upper(v)
  if utils.tableContains(allowedVerbs, verb) then
    ngx.req.set_method(ngx[utils.concatStrings({"HTTP_", verb})])
  else
    ngx.req.set_method(ngx.HTTP_GET)
  end
end

function setRequestLogs()
  local requestHeaders = ngx.req.get_headers()
  for k, v in pairs(requestHeaders) do
    if k == 'authorization' or k == _G.clientSecretName then
      requestHeaders[k] = '[redacted]'
    end
  end
  ngx.var.requestHeaders = cjson.encode(requestHeaders)
  ngx.req.read_body()
  ngx.var.requestBody = ngx.req.get_body_data()
end

function _M.setResponseLogs()
  ngx.var.responseHeaders = cjson.encode(ngx.resp.get_headers())
  local resp_body = ngx.arg[1]
  ngx.ctx.buffered = (ngx.ctx.buffered or '') .. resp_body
  if ngx.arg[2] then
    ngx.var.responseBody = ngx.ctx.buffered
  end
end

return _M
