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

local request = require 'lib/request'
local cjson = require 'cjson'
local utils = require "lib/utils"

local _M = {}

local function exchangeOAuthToken(dataStore, token, facebookAppToken)
  local http = require 'resty.http'
  local request = require "lib/request"
  local httpc = http.new()

  local request_options = {
    headers = {
      ['Accept'] = 'application/json'
    },
    ssl_verify = false
  }
  local envUrl = os.getenv('TOKEN_FACEBOOK_URL')
  envUrl = envUrl ~= nil and envUrl or 'https://graph.facebook.com/debug_token'
  local request_uri = utils.concatStrings({envUrl, '?input_token=', token,  '&access_token=', facebookAppToken})
  local res, err = httpc:request_uri(request_uri, request_options)
-- convert response
  if not res then
    ngx.log(ngx.WARN, 'Could not invoke Facebook API. Error=', err)
    request.err(500, 'Connection to the OAuth provider failed.')
    return
  end
  local json_resp = cjson.decode(res.body)
  if json_resp['error'] ~= nil then
    return nil
  end

  if (json_resp['error']) then
    return nil
  end
  -- keep token in cache until it expires
  local ttl = json_resp.data['expires_at'] - os.time()
  dataStore:saveOAuthToken('facebook', utils.concatStrings({token, facebookAppToken}), cjson.encode(json_resp), ttl)
  return json_resp
end

function _M.process(dataStore, token)

  local headerName = utils.concatStrings({'http_', 'x-facebook-app-token'}):gsub("-", "_")

  local facebookAppToken = ngx.var[headerName]
  if facebookAppToken == nil then
    request.err(401, 'Facebook requires you provide an app token to validate user tokens. Provide a X-Facebook-App-Token header')
    return nil
  end

  local result = dataStore:getOAuthToken('facebook', utils.concatStrings({token, facebookAppToken}))
  if result ~= ngx.null then
    return cjson.decode(result)
  end

   return exchangeOAuthToken(dataStore, token, facebookAppToken)
end

return _M
