--
-- 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 require      = require
local yaml         = require("tinyyaml")
local log          = require("apisix.core.log")
local profile      = require("apisix.core.profile")
local lfs          = require("lfs")
local inspect      = require("inspect")
local io           = io
local ngx          = ngx
local re_find      = ngx.re.find
local get_headers  = ngx.req.get_headers
local type         = type
local pairs        = pairs
local setmetatable = setmetatable
local pcall        = pcall
local ipairs       = ipairs
local unpack       = unpack
local debug_yaml_path = profile:yaml_path("debug")
local debug_yaml
local debug_yaml_ctime


local _M = {version = 0.1}


local function read_debug_yaml()
    local attributes, err = lfs.attributes(debug_yaml_path)
    if not attributes then
        log.notice("failed to fetch ", debug_yaml_path, " attributes: ", err)
        return
    end

    -- log.info("change: ", json.encode(attributes))
    local last_change_time = attributes.change
    if debug_yaml_ctime == last_change_time then
        return
    end

    local f, err = io.open(debug_yaml_path, "r")
    if not f then
        log.error("failed to open file ", debug_yaml_path, " : ", err)
        return
    end

    local found_end_flag
    for i = 1, 10 do
        f:seek('end', -i)

        local end_flag = f:read("*a")
        -- log.info(i, " flag: ", end_flag)
        if re_find(end_flag, [[#END\s*]], "jo") then
            found_end_flag = true
            break
        end
    end

    if not found_end_flag then
        f:seek("set")
        local size = f:seek("end")
        f:close()

        if size > 8 then
            log.warn("missing valid end flag in file ", debug_yaml_path)
        end
        return
    end

    f:seek('set')
    local yaml_config = f:read("*a")
    f:close()

    local debug_yaml_new = yaml.parse(yaml_config)
    if not debug_yaml_new then
        log.error("failed to parse the content of file " .. debug_yaml_path)
        return
    end

    debug_yaml_new.hooks = debug_yaml_new.hooks or {}
    debug_yaml = debug_yaml_new
    debug_yaml_ctime = last_change_time
end


local sync_debug_hooks
do
    local pre_mtime
    local enabled_hooks = {}

local function apple_new_fun(module, fun_name, file_path, hook_conf)
    local log_level = hook_conf.log_level or "warn"

    if not module or type(module[fun_name]) ~= "function" then
        log.error("failed to find function [", fun_name,
                  "] in module:", file_path)
        return
    end

    local fun = module[fun_name]
    local fun_org
    if enabled_hooks[fun] then
        fun_org = enabled_hooks[fun].org
        enabled_hooks[fun] = nil
    else
        fun_org = fun
    end

    local t = {fun_org = fun_org}
    local mt = {}

    function mt.__call(self, ...)
        local arg = {...}
        local http_filter = debug_yaml.http_filter
        local api_ctx = ngx.ctx.api_ctx
        local enable_by_hook = not (http_filter and http_filter.enable)
        local enable_by_header_filter = (http_filter and http_filter.enable)
                and (api_ctx and api_ctx.enable_dynamic_debug)
        if hook_conf.is_print_input_args then
            if enable_by_hook or enable_by_header_filter then
                log[log_level]("call require(\"", file_path, "\").", fun_name,
                               "() args:", inspect(arg))
            end
        end

        local ret = {self.fun_org(...)}
        if hook_conf.is_print_return_value then
            if enable_by_hook or enable_by_header_filter then
                log[log_level]("call require(\"", file_path, "\").", fun_name,
                               "() return:", inspect(ret))
            end
        end
        return unpack(ret)
    end

    setmetatable(t, mt)
    enabled_hooks[t] = {
        org = fun_org, new = t, mod = module,
        fun_name = fun_name
    }
    module[fun_name] = t
end


function sync_debug_hooks()
    if not debug_yaml_ctime or debug_yaml_ctime == pre_mtime then
        return
    end

    for _, hook in pairs(enabled_hooks) do
        local m = hook.mod
        local name = hook.fun_name
        m[name] = hook.org
    end

    enabled_hooks = {}

    local hook_conf = debug_yaml.hook_conf
    if not hook_conf.enable then
        pre_mtime = debug_yaml_ctime
        return
    end

    local hook_name = hook_conf.name or ""
    local hooks = debug_yaml[hook_name]
    if not hooks then
        pre_mtime = debug_yaml_ctime
        return
    end

    for file_path, fun_names in pairs(hooks) do
        local ok, module = pcall(require, file_path)
        if not ok then
            log.error("failed to load module [", file_path, "]: ", module)

        else
            for _, fun_name in ipairs(fun_names) do
                apple_new_fun(module, fun_name, file_path, hook_conf)
            end
        end
    end

    pre_mtime = debug_yaml_ctime
end

end --do


local function sync_debug_status(premature)
    if premature then
        return
    end

    read_debug_yaml()
    sync_debug_hooks()
end


local function check()
    if not debug_yaml or not debug_yaml.http_filter then
        return false
    end

    local http_filter = debug_yaml.http_filter
    if not http_filter or not http_filter.enable_header_name or not http_filter.enable then
        return false
    end

    return true
end

function _M.dynamic_debug(api_ctx)
    if not check() then
        return
    end

    if get_headers()[debug_yaml.http_filter.enable_header_name] then
        api_ctx.enable_dynamic_debug = true
    end
end


function _M.enable_debug()
    if not debug_yaml or not debug_yaml.basic then
        return false
    end

    return debug_yaml.basic.enable
end


function _M.init_worker()
    local process = require("ngx.process")
    if process.type() ~= "worker" then
        return
    end

    sync_debug_status()
    ngx.timer.every(1, sync_debug_status)
end


return _M
