-- Copyright (c) 2016 IBM. All rights reserved.
--
--   Permission is hereby granted, free of charge, to any person obtaining a
--   copy of this software and associated documentation files (the "Software"),
--   to deal in the Software without restriction, including without limitation
--   the rights to use, copy, modify, merge, publish, distribute, sublicense,
--   and/or sell copies of the Software, and to permit persons to whom the
--   Software is furnished to do so, subject to the following conditions:
--
--   The above copyright notice and this permission notice shall be included in
--   all copies or substantial portions of the Software.
--
--   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
--   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
--   DEALINGS IN THE SOFTWARE.

--- @module management
-- Defines and exposes a lightweight API management to create and remove resources in the running API Gateway
-- @author Alex Song (songs)

local cjson = require "cjson"
local redis = require "lib/redis"
local utils = require "lib/utils"
local logger = require "lib/logger"
local request = require "lib/request"
local MANAGEDURL_HOST = os.getenv("PUBLIC_MANAGEDURL_HOST")
MANAGEDURL_HOST = (MANAGEDURL_HOST ~= nil and MANAGEDURL_HOST ~= '') and MANAGEDURL_HOST or "0.0.0.0"
local MANAGEDURL_PORT = os.getenv("PUBLIC_MANAGEDURL_PORT")
MANAGEDURL_PORT = (MANAGEDURL_PORT ~= nil and MANAGEDURL_PORT ~= '') and MANAGEDURL_PORT or "8080"
local REDIS_HOST = os.getenv("REDIS_HOST")
local REDIS_PORT = os.getenv("REDIS_PORT")
local REDIS_PASS = os.getenv("REDIS_PASS")
local REDIS_FIELD = "resources"
local BASE_CONF_DIR = "/etc/api-gateway/managed_confs/"

local _M = {}

--------------------------
---------- APIs ----------
--------------------------

--- Add an api to the Gateway
-- PUT /APIs
-- body:
-- {
--    "name": *(String) name of API
--    "basePath": *(String) base path for api
--    "tenantId": *(String) tenant id
--    "resources": *(String) resources to add
-- }
function _M.addAPI()
  -- Open connection to redis or use one from connection pool
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  -- Check for api id from uri and use existingAPI if it already exists in redis
  local uri = string.gsub(ngx.var.request_uri, "?.*", "")
  local existingAPI = checkURIForExisting(red, uri, "api")
  -- Read in the PUT JSON Body
  ngx.req.read_body()
  local args = ngx.req.get_body_data()
  if not args then
    request.err(400, "Missing request body")
  end
  -- Convert json into Lua table
  local decoded = cjson.decode(args)
  -- Check for api id in JSON body
  if existingAPI == nil and decoded.id ~= nil then
    existingAPI = redis.getAPI(red, decoded.id)
    if existingAPI == nil then
      request.err(404, utils.concatStrings({"Unknown API id ", decoded.id}))
    end
  end
  -- Error checking
  local fields = {"name", "basePath", "tenantId", "resources"}
  for k, v in pairs(fields) do
    local res, err = isValid(red, v, decoded[v])
    if res == false then
      request.err(err.statusCode, err.message)
    end
  end
  -- Format basePath
  local basePath = decoded.basePath:sub(1,1) == '/' and decoded.basePath:sub(2) or decoded.basePath
  -- Create managedUrl object
  local uuid = existingAPI ~= nil and existingAPI.id or utils.uuid()
  local managedUrl = utils.concatStrings({"http://", MANAGEDURL_HOST, ":", MANAGEDURL_PORT, "/api/", decoded.tenantId})
  if basePath:sub(1,1) ~= '' then
    managedUrl = utils.concatStrings({managedUrl, "/", basePath})
  end
  local managedUrlObj = {
    id = uuid,
    name = decoded.name,
    basePath = utils.concatStrings({"/", basePath}),
    tenantId = decoded.tenantId,
    resources = decoded.resources,
    managedUrl = managedUrl
  }
  -- Add API object to redis
  managedUrlObj = redis.addAPI(red, uuid, managedUrlObj, existingAPI)
  -- Add resources to redis
  for path, resource in pairs(decoded.resources) do
    local gatewayPath = utils.concatStrings({basePath, ngx.escape_uri(path)})
    addResource(red, resource, gatewayPath, decoded.tenantId)
  end
  redis.close(red)
  -- Return managed url object
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, managedUrlObj)
end

--- Check JSON body fields for errors
-- @param red Redis client instance
-- @param field name of field
-- @param object field object
function isValid(red, field, object)
  -- Check that field exists in body
  if not object then
    return false, { statusCode = 400, message = utils.concatStrings({"Missing field '", field, "' in request body."}) }
  end
  -- Additional check f or tenantId
  if field == "tenantId" then
    local tenant = redis.getTenant(red, object)
    if tenant == nil then
      return false, { statusCode = 404, message = utils.concatStrings({"Unknown tenant id ", object }) }
    end
  end
  -- Additional checks for resource object
  if field == "resources" then
    local resources = object
    if next(object) == nil then
      return false, { statusCode = 400, message = "Empty resources object." }
    end
    for path, resource in pairs(resources) do
      -- Check that resource path begins with slash
      if path:sub(1,1) ~= '/' then
        return false, { statusCode = 400, message = "Resource path must begin with '/'." }
      end
      -- Check operations object
      if not resource.operations or next(resource.operations) == nil then
        return false, { statusCode = 400, message = "Missing or empty field 'operations' or in resource path object." }
      end
      for verb, verbObj in pairs(resource.operations) do
        local allowedVerbs = {GET=true, POST=true, PUT=true, DELETE=true, PATCH=true, HEAD=true, OPTIONS=true}
        if allowedVerbs[verb:upper()] == nil then
          return false, { statusCode = 400, message = utils.concatStrings({"Resource verb '", verb, "' not supported."}) }
        end
        -- Check required fields
        local requiredFields = {"backendMethod", "backendUrl"}
        for k, v in pairs(requiredFields) do
          if verbObj[v] == nil then
            return false, { statusCode = 400, message = utils.concatStrings({"Missing field '", v, "' for '", verb, "' operation."}) }
          end
          if v == "backendMethod" then
            local backendMethod = verbObj[v]
            if allowedVerbs[backendMethod:upper()] == nil then
              return false, { statusCode = 400, message = utils.concatStrings({"backendMethod '", backendMethod, "' not supported."}) }
            end
          end
        end
        -- Check optional fields
        local policies = verbObj.policies
        if policies then
          for k, v in pairs(policies) do
            if v.type == nil then
              return false, { statusCode = 400, message = "Missing field 'type' in policy object." }
            end
          end
        end
        local security = verbObj.security
        if security and security.type == nil then
          return false, { statusCode = 400, message = "Missing field 'type' in security object." }
        end
      end
    end
  end
  -- All error checks passed
  return true
end

--- Helper function for adding a resource to redis and creating an nginx conf file
-- @param red
-- @param resource
-- @param gatewayPath
-- @param tenantId
function addResource(red, resource, gatewayPath, tenantId)
  -- Create resource object and add to redis
  local redisKey = utils.concatStrings({"resources", ":", tenantId, ":", ngx.unescape_uri(gatewayPath)})
  local apiId
  local operations
  for k, v in pairs(resource) do
    if k == 'apiId' then
      apiId = v
    elseif k == 'operations' then
      operations = v
    end
  end
  local resourceObj = redis.generateResourceObj(operations, apiId)
  redis.createResource(red, redisKey, REDIS_FIELD, resourceObj)
end

--- Get one or all APIs from the gateway
-- GET /APIs
function _M.getAPIs()
  local uri = string.gsub(ngx.var.request_uri, "?.*", "")
  local id
  local index = 1
  local tenantQuery = false
  for word in string.gmatch(uri, '([^/]+)') do
    if index == 3 then
      id = word
    elseif index == 4 then
      if word == 'tenant' then
        tenantQuery = true
      else
        request.err(400, "Invalid request")
      end
    end
    index = index + 1
  end
  if id == nil then
    getAllAPIs()
  else
    if tenantQuery == false then
      getAPI(id)
    else
      getAPITenant(id)
    end
  end
end

--- Get all APIs in redis
function getAllAPIs()
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local res = redis.getAllAPIs(red)
  redis.close(red)
  local apiList = {}
  for k, v in pairs(res) do
    if k%2 == 0 then
      apiList[#apiList+1] = cjson.decode(v)
    end
  end
  apiList = cjson.encode(apiList)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, apiList)
end

--- Get API by its id
-- @param id of API
function getAPI(id)
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local api = redis.getAPI(red, id)
  if api == nil then
    request.err(404, utils.concatStrings({"Unknown api id ", id}))
  end
  redis.close(red)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, cjson.encode(api))
end

--- Get belongsTo relation tenant
-- @param id id of API
function getAPITenant(id)
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local api = redis.getAPI(red, id)
  if api == nil then
    request.err(404, utils.concatStrings({"Unknown api id ", id}))
  end
  local tenantId = api.tenantId
  local tenant = redis.getTenant(red, tenantId)
  if tenant == nil then
    request.err(404, utils.concatStrings({"Unknown tenant id ", tenantId}))
  end
  redis.close(red)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, cjson.encode(tenant))
end

--- Delete API from gateway
-- DELETE /APIs/<id>
function _M.deleteAPI()
  local uri = string.gsub(ngx.var.request_uri, "?.*", "")
  local index = 1
  local id
  for word in string.gmatch(uri, '([^/]+)') do
    if index == 3 then
      id = word
    end
    index = index + 1
  end
  if id == nil then
    request.err(400, "No id specified.")
  end
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local api = redis.getAPI(red, id)
  if api == nil then
    request.err(404, utils.concatStrings({"Unknown API id ", id}))
  end
  -- Delete API
  redis.deleteAPI(red, id)
  -- Delete all resources for the API
  local basePath = api.basePath:sub(2)
  for path, v in pairs(api.resources) do
    local gatewayPath = utils.concatStrings({basePath, ngx.escape_uri(path)})
    deleteResource(red, gatewayPath, api.tenantId)
  end
  redis.close(red)
  request.success(200, {})
end

--- Helper function for deleting resource in redis and appropriate conf files
-- @param red redis instance
-- @param gatewayPath path in gateway
-- @param tenantId tenant id
function deleteResource(red, gatewayPath, tenantId)
  local redisKey = utils.concatStrings({"resources:", tenantId, ":", ngx.unescape_uri(gatewayPath)})
  redis.deleteResource(red, redisKey, REDIS_FIELD)
end

-----------------------------
---------- Tenants ----------
-----------------------------

--- Add a tenant to the Gateway
-- PUT /Tenants
-- body:
-- {
--    "namespace": *(String) tenant namespace
--    "instance": *(String) tenant instance
-- }
function _M.addTenant()
  -- Open connection to redis or use one from connection pool
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  -- Check for tenant id and use existingTenant if it already exists in redis
  local uri = string.gsub(ngx.var.request_uri, "?.*", "")
  local existingTenant = checkURIForExisting(red, uri, "tenant")
  -- Read in the PUT JSON Body
  ngx.req.read_body()
  local args = ngx.req.get_body_data()
  if not args then
    request.err(400, "Missing request body")
  end
  -- Convert json into Lua table
  local decoded = cjson.decode(args)
  -- Check for tenant id in JSON body
  if existingTenant == nil and decoded.id ~= nil then
    existingTenant = redis.getTenant(red, decoded.id)
    if existingTenant == nil then
      request.err(404, utils.concatStrings({"Unknown Tenant id ", decoded.id}))
    end
  end
  -- Error checking
  local fields = {"namespace", "instance"}
  for k, v in pairs(fields) do
    if not decoded[v] then
      request.err(400, utils.concatStrings({"Missing field '", v, "' in request body."}))
    end
  end
  -- Return tenant object
  local uuid = existingTenant ~= nil and existingTenant.id or utils.uuid()
  local tenantObj = {
    id = uuid,
    namespace = decoded.namespace,
    instance = decoded.instance
  }
  tenantObj = redis.addTenant(red, uuid, tenantObj)
  redis.close(red)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, tenantObj)
end

--- Get one or all tenants from the gateway
-- GET /Tenants
function _M.getTenants()
  local uri = string.gsub(ngx.var.request_uri, "?.*", "")
  local id
  local index = 1
  local apiQuery = false
  for word in string.gmatch(uri, '([^/]+)') do
    if index == 3 then
      id = word
    elseif index == 4 then
      if word:lower() == 'apis' then
        apiQuery = true
      else
        request.err(400, "Invalid request")
      end
    end
    index = index + 1
  end
  if id == nil then
    getAllTenants()
  else
    if apiQuery == false then
      getTenant(id)
    else
      getTenantAPIs(id)
    end
  end
end

--- Get all tenants in redis
function getAllTenants()
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local res = redis.getAllTenants(red)
  redis.close(red)
  local tenantList = {}
  for k, v in pairs(res) do
    if k%2 == 0 then
      tenantList[#tenantList+1] = cjson.decode(v)
    end
  end
  tenantList = cjson.encode(tenantList)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, tenantList)
end

--- Get tenant by its id
-- @param id tenant id
function getTenant(id)
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local tenant = redis.getTenant(red, id)
  if tenant == nil then
    request.err(404, utils.concatStrings({"Unknown tenant id ", id }))
  end
  redis.close(red)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, cjson.encode(tenant))
end

--- Get APIs associated with tenant
-- @param id tenant id
function getTenantAPIs(id)
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local res = redis.getAllAPIs(red)
  redis.close(red)
  local apiList = {}
  for k, v in pairs(res) do
    if k%2 == 0 then
      local decoded = cjson.decode(v)
      if decoded.tenantId == id then
        apiList[#apiList+1] = decoded
      end
    end
  end
  apiList = cjson.encode(apiList)
  ngx.header.content_type = "application/json; charset=utf-8"
  request.success(200, apiList)
end

--- Delete tenant from gateway
-- DELETE /Tenants/<id>
function _M.deleteTenant()
  local uri = string.gsub(ngx.var.request_uri, "?.*", "")
  local index = 1
  local id
  for word in string.gmatch(uri, '([^/]+)') do
    if index == 3 then
      id = word
    end
    index = index + 1
  end
  if id == nil then
    request.err(400, "No id specified.")
  end
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  redis.deleteTenant(red, id)
  redis.close(red)
  request.success(200, {})
end

------------------------------
----- Pub/Sub with Redis -----
------------------------------

--- Sync with redis
-- GET /v1/sync
function _M.sync()
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 10000)
  logger.debug(utils.concatStrings({"Connected to redis at ", REDIS_HOST, ":", REDIS_PORT}))
  redis.syncWithRedis(red)
  ngx.exit(200)
end

--- Subscribe to redis
-- GET /v1/subscribe
function _M.subscribe()
  local redisGetClient = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  local redisSubClient = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  redis.subscribe(redisSubClient, redisGetClient)
  ngx.exit(200)
end

---------------------------
------ Subscriptions ------
---------------------------

--- Add an apikey/subscription to redis
-- PUT /subscriptions
-- Body:
-- {
--    key: *(String) key for tenant/api/resource
--    scope: *(String) tenant or api or resource
--    tenant: *(String) tenant id
--    resource: (String) url-encoded resource path
--    api: (String) api id
-- }
function _M.addSubscription()
  -- Validate body and create redisKey
  local redisKey = validateSubscriptionBody()
  -- Open connection to redis or use one from connection pool
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  redis.createSubscription(red, redisKey)
  -- Add current redis connection in the ngx_lua cosocket connection pool
  redis.close(red)
  request.success(200, "Subscription created.")
end

--- Delete apikey/subscription from redis
-- DELETE /subscriptions
-- Body:
-- {
--    key: *(String) key for tenant/api/resource
--    scope: *(String) tenant or api or resource
--    tenant: *(String) tenant id
--    resource: (String) url-encoded resource path
--    api: (String) api id
-- }
function _M.deleteSubscription()
  -- Validate body and create redisKey
  local redisKey = validateSubscriptionBody()
  -- Initialize and connect to redis
  local red = redis.init(REDIS_HOST, REDIS_PORT, REDIS_PASS, 1000)
  -- Return if subscription doesn't exist
  redis.deleteSubscription(red, redisKey)
  -- Add current redis connection in the ngx_lua cosocket connection pool
  redis.close(red)
  request.success(200, "Subscription deleted.")
end

--- Check the request JSON body for correct fields
-- @return redisKey subscription key for redis
function validateSubscriptionBody()
  -- Read in the PUT JSON Body
  ngx.req.read_body()
  local args = ngx.req.get_post_args()
  if not args then
    request.err(400, "Missing request body.")
  end
  -- Convert json into Lua table
  local decoded
  if next(args) then
    decoded = utils.convertJSONBody(args)
  else
    request.err(400, "Request body required.")
  end
  -- Check required fields
  local requiredFieldList = {"key", "scope", "tenant"}
  for i, field in ipairs(requiredFieldList) do
    if not decoded[field] then
      request.err(400, utils.concatStrings({"\"", field, "\" missing from request body."}))
    end
  end
  -- Check if we're using tenant or resource or api
  local resource = decoded.resource
  local apiId = decoded.apiId
  local redisKey
  local prefix = utils.concatStrings({"subscriptions:tenant:", decoded.tenant})
  if decoded.scope == "tenant" then
    redisKey = prefix
  elseif decoded.scope == "resource" then
    if resource ~= nil then
      redisKey = utils.concatStrings({prefix, ":resource:", resource})
    else
      request.err(400, "\"resource\" missing from request body.")
    end
  elseif decoded.scope == "api" then
    if apiId ~= nil then
      redisKey = utils.concatStrings({prefix, ":api:", apiId})
    else
      request.err(400, "\"apiId\" missing from request body.")
    end
  else 
    request.err(400, "Invalid scope")
  end
  redisKey = utils.concatStrings({redisKey, ":key:", decoded.key})
  return redisKey
end


--- Check for api id from uri and use existingAPI if it already exists in redis
-- @param red Redis client instance
-- @param uri Uri of request. Eg. /v1/apis/{id}
-- @param type type to look for in redis. "api" or "tenant"
function checkURIForExisting(red, uri, type)
  local id, existing
  local index = 1
  -- Check if id is in the uri
  for word in string.gmatch(uri, '([^/]+)') do
    if index == 3 then
      id = word
    end
    index = index + 1
  end
  -- Get object from redis
  if id ~= nil then
    if type == "api" then
      existing = redis.getAPI(red, id)
      if existing == nil then
        request.err(404, utils.concatStrings({"Unknown API id ", id}))
      end
    elseif type == "tenant" then
      existing = redis.getTenant(red, id)
      if existing == nil then
        request.err(404, utils.concatStrings({"Unknown Tenant id ", id}))
      end
    end
  end
  return existing
end

--- Parse the request uri to get the redisKey, tenant, and gatewayPath
-- @param requestURI String containing the uri in the form of "/resources/<tenant>/<path>"
-- @return list containing redisKey, tenant, gatewayPath
function parseRequestURI(requestURI)
  local list = {}
  for i in string.gmatch(requestURI, '([^/]+)') do
    list[#list + 1] = i
  end
  if not list[1] or not list[2] then
    request.err(400, "Request path should be \"/resources/<tenant>/<url-encoded-resource>\"")
  end

  return list  --prefix, tenant, gatewayPath, apiKey
end

return _M
