--
-- 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 core = require("apisix.core")
local timers = require("apisix.timers")
local process = require("ngx.process")
local signal = require("resty.signal")
local ngx = ngx
local lfs = require("lfs")
local io = io
local os = os
local table = table
local string = string
local str_find = core.string.find
local local_conf


local plugin_name = "log-rotate"
local INTERVAL = 60 * 60    -- rotate interval (unit: second)
local MAX_KEPT = 24 * 7     -- max number of log files will be kept
local schema = {
    type = "object",
    properties = {},
    additionalProperties = false,
}


local _M = {
    version = 0.1,
    priority = 100,
    name = plugin_name,
    schema = schema,
}


local function file_exists(path)
    local file = io.open(path, "r")
    if file then
        file:close()
    end
    return file ~= nil
end


local function get_last_index(str, key)
    local rev = string.reverse(str)
    local _, idx = str_find(rev, key)
    local n
    if idx then
        n = #rev - idx + 1
    end

    return n
end


local function get_log_path_info(file_type)
    local_conf = core.config.local_conf()
    local conf_path
    if file_type == "error.log" then
        conf_path = local_conf and local_conf.nginx_config and
        local_conf.nginx_config.error_log
    else
        conf_path = local_conf and local_conf.nginx_config and
        local_conf.nginx_config.http and
        local_conf.nginx_config.http.access_log
    end

    local prefix = ngx.config.prefix()

    if conf_path then
        local root = string.sub(conf_path, 1, 1)
        -- relative path
        if root ~= "/" then
            conf_path = prefix .. conf_path
        end
        local n = get_last_index(conf_path, "/")
        if n ~= nil and n ~= #conf_path then
            local dir = string.sub(conf_path, 1, n)
            local name = string.sub(conf_path, n + 1)
            return dir, name
        end
    end

    return prefix .. "logs/", file_type
end


local function rotate_file(date_str, file_type)
    local log_dir, filename = get_log_path_info(file_type)

    core.log.info("rotate log_dir:", log_dir)
    core.log.info("rotate filename:", filename)

    local file_path = log_dir .. date_str .. "__" .. filename
    if file_exists(file_path) then
        core.log.info("file exist: ", file_path)
        return false
    end

    local file_path_org = log_dir .. filename
    local ok, msg = os.rename(file_path_org, file_path)
    core.log.info("move file from ", file_path_org, " to ", file_path,
                  " res:", ok, " msg:", msg)
    return true
end


local function tab_sort(a, b)
    return a > b
end

local function scan_log_folder()
    local t = {
        access = {},
        error = {},
    }

    local log_dir, access_name = get_log_path_info("access.log")
    local _, error_name = get_log_path_info("error.log")

    for file in lfs.dir(log_dir) do
        local n = get_last_index(file, "__")
        if n ~= nil then
            local log_type = file:sub(n + 2)
            if log_type == access_name then
                table.insert(t.access, file)
            elseif log_type == error_name then
                table.insert(t.error, file)
            end
        end
    end

    table.sort(t.access, tab_sort)
    table.sort(t.error, tab_sort)
    return t
end


local function rotate()
    local local_conf = core.config.local_conf()
    local interval = INTERVAL
    local max_kept = MAX_KEPT
    local attr = core.table.try_read_attr(local_conf, "plugin_attr",
                                          "log-rotate")
    if attr then
        interval = attr.interval or interval
        max_kept = attr.max_kept or max_kept
    end

    core.log.info("rotate interval:", interval)
    core.log.info("rotate max keep:", max_kept)

    local time = ngx.time()
    if time % interval == 0 then
        time = time - interval
    else
        time = time - time % interval
    end

    local date_str = os.date("%Y-%m-%d_%H-%M-%S", time)

    local ok1 = rotate_file(date_str, "access.log")
    local ok2 = rotate_file(date_str, "error.log")
    if not ok1 and not ok2 then
        return
    end

    core.log.warn("send USER1 signal to master process [",
                  process.get_master_pid(), "] for reopening log file")
    local ok, err = signal.kill(process.get_master_pid(), signal.signum("USR1"))
    if not ok then
        core.log.error("failed to send USER1 signal for reopening log file: ",
                       err)
    end

    -- clean the oldest file
    local log_list = scan_log_folder()
    local log_dir, _ = get_log_path_info("access.log")
    for i = max_kept + 1, #log_list.error do
        local path = log_dir .. log_list.error[i]
        local ok = os.remove(path)
        core.log.warn("remove old error file: ", path, " ret: ", ok)
    end

    for i = max_kept + 1, #log_list.access do
        local path = log_dir .. log_list.access[i]
        local ok = os.remove(path)
        core.log.warn("remove old access file: ", path, " ret: ", ok)
    end
end


function _M.init()
    timers.register_timer("plugin#log-rotate", rotate, true)
end


function _M.destroy()
    timers.unregister_timer("plugin#log-rotate", true)
end


return _M
