--Copyright 2021 The casbin Authors. All Rights Reserved.
--
--Licensed 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 rex = require ("rex_pcre2")
local posix = require("posix.fnmatch")

local BuiltInFunctions = {}

function BuiltInFunctions.validateVariadicArgs(expectedLen, args)
    if #args ~= expectedLen then
        return error("Expected "..expectedLen.." arguments, but got "..#args)
    end
    for i=1,expectedLen do
        if type(args[i])~="string" then
            return error("Argument must be a string")
        end
    end
end

-- KeyMatch determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
-- For example, "/foo/bar" matches "/foo/*"
function BuiltInFunctions.keyMatch(key1, key2)
    local i, _ = string.find(key2, "*")

    if not i then
        return (key1 == key2)
    end

    if #key1>=i then
        return (string.sub(key1, 1, i-1) == string.sub(key2, 1, i-1))
    end
    return (key1 == string.sub(key2, 1, i-1))
end

-- Wrapper for keyMatch
function BuiltInFunctions.keyMatchFunc(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.keyMatch(args[1], args[2])
end

-- KeyGet returns the matched part
-- For example, "/foo/bar/foo" matches "/foo/*"
-- "bar/foo" will been returned
function BuiltInFunctions.keyGet(key1, key2)
    local i, _ = string.find(key2, "*")

    if not i then
        return ""
    end
    if #key1>=i then
        if string.sub(key1, 1, i-1) == string.sub(key2, 1, i-1)  then
            return string.sub(key1, i)
        end
    end
    return ""
end

-- Wrapper for keyGet
function BuiltInFunctions.keyGetFunc(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.keyGet(args[1], args[2])
end

-- KeyMatch2 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
-- For example, "/foo/bar" matches "/foo/*", "/resource1" matches "/:resource"
function BuiltInFunctions.keyMatch2(key1, key2)
    key2 = string.gsub(key2, "/%*", "/.*")
    if key2 == "*" then key2 = ".*" end
    local key = rex.gsub(key2, ":[^/]+", "[^/]+")
	return BuiltInFunctions.regexMatch(key1, "^"..key.."$")
end

-- Wrapper for keyMatch2
function BuiltInFunctions.keyMatch2Func(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.keyMatch2(args[1], args[2])
end

-- KeyGet2 returns value matched pattern
-- For example, "/resource1" matches "/:resource"
-- if the pathVar == "resource", then "resource1" will be returned
function BuiltInFunctions.keyGet2(key1, key2 , pathVar)
    key2 = string.gsub(key2, "/%*", "/.*")
    local keys ={}
    local repl=function(s)
        table.insert(keys, string.sub(s, 1, -1))
        return "([^/]+)"
    end
    key2 = string.gsub(key2,":[^/]+",repl)
    key2 = "^" .. key2 .. "$"
    local values = {string.match(key1,key2)}
    if #values == 0 then
        return ""
    end
    for i, key in pairs(keys) do
        if pathVar == string.sub(key,2,-1) then
            return values[i]
        end
    end
    return ""
end

-- Wrapper for KeyGet2
function BuiltInFunctions.keyGet2Func(args)
    BuiltInFunctions.validateVariadicArgs(3, args)
    return BuiltInFunctions.keyGet2(args[1], args[2],args[3])
end

-- KeyMatch3 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
-- For example, "/foo/bar" matches "/foo/*", "/resource1" matches "/{resource}"
function BuiltInFunctions.keyMatch3(key1, key2)
    key2 = string.gsub(key2, "/%*", "/.*")
    local key = rex.gsub(key2, "{[^/]+}", "[^/]+")
	return BuiltInFunctions.regexMatch(key1, "^"..key.."$")
end

-- Wrapper for keyMatch3
function BuiltInFunctions.keyMatch3Func(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.keyMatch3(args[1], args[2])
end

-- KeyMatch4 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
-- Besides what KeyMatch3 does, KeyMatch4 can also match repeated patterns:
-- "/parent/123/child/123" matches "/parent/{id}/child/{id}"
-- "/parent/123/child/456" does not match "/parent/{id}/child/{id}"
-- But KeyMatch3 will match both.
function BuiltInFunctions.keyMatch4(key1, key2)
    key2 = string.gsub(key2, "/%*", "/.*")
    local tokens={}
    local repl=function(s)
        table.insert(tokens, string.sub(s, 1, -1))
        return "([^/]+)"
    end
    key2=string.gsub(key2,"{([^/]+)}",repl)
    if string.match(key1, key2)==nil then
        return false
    end
    local matches={string.match(key1, key2)}
    if #tokens~= #matches then
        error("KeyMatch4: number of tokens is not equal to number of values")
    end
    local values={}
    for key, token in pairs(tokens) do
        if values[token]==nil then
            values[token] = matches[key]
        end
        if values[token] ~= matches[key] then
            return false
        end
    end

    return true
end

-- Wrapper for keyMatch4
function BuiltInFunctions.keyMatch4Func(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.keyMatch4(args[1], args[2])
end

-- KeyMatch5 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *
-- For example,
-- - "/foo/bar?status=1&type=2" matches "/foo/bar"
-- - "/parent/child1" and "/parent/child1" matches "/parent/*"
-- - "/parent/child1?status=1" matches "/parent/*"
function BuiltInFunctions.keyMatch5(key1, key2)
    local i = string.find(key1, "?", 1, true)

    if i then
        key1 = string.sub(key1, 1, i - 1)
    end

    key2 = string.gsub(key2, "/%*", "/.*")
    key2 = string.gsub(key2, "%{[^/]+%}", "[^/]+")

    return string.match(key1, "^" .. key2 .. "$") ~= nil
end

-- Wrapper for keyMatch5
function BuiltInFunctions.keyMatch5Func(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.keyMatch5(args[1], args[2])
end

-- RegexMatch determines whether key1 matches the pattern of key2 in regular expression.
function BuiltInFunctions.regexMatch(key1, key2)
    local res = rex.match(key1, key2)
    if res then
        return true
    else
        return false
    end
end

-- Wrapper for regexMatch
function BuiltInFunctions.regexMatchFunc(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.regexMatch(args[1], args[2])
end

-- IPMatch determines whether IP address ip1 matches the pattern of IP address ip2, ip2 can be an IP address or a CIDR pattern.
-- For example, "192.168.2.123" matches "192.168.2.0/24"
function BuiltInFunctions.IPMatch(ip1, ip2)
    local getip1 = {string.match(ip1,"(%d+)%.(%d+)%.(%d+)%.(%d+)" )}
    local objIP1=0
    for i=1,4 do
        if getip1[i]==nil or tonumber(getip1[i])>255 or tonumber(getip1[i])<0 then
            error("invalid argument: ip1 in IPMatch() function is not an IP address.")
        else
            objIP1=objIP1+2^(8*(4-i))*getip1[i]
        end
    end
    if ip1==ip2 then
        return true
    end

    local cidr
    ip2=string.gsub(ip2,"/(%d+)",function(s) cidr=s return "" end)
    local getip2 = {string.match(ip2,"(%d+)%.(%d+)%.(%d+)%.(%d+)" )}
    local objIP2=0
    for i=1,4 do
        if getip2[i]==nil or tonumber(getip2[i])>255 or tonumber(getip2[i])<0 then
            error("invalid argument: ip1 in IPMatch() function is not an IP address.")
        else
            objIP2=objIP2+2^(8*(4-i))*getip2[i]
        end
    end
    if cidr==nil then
        return false
    else
        local number1,_=math.modf(objIP1/(2^(32-cidr)))
        local number2,_=math.modf(objIP2/(2^(32-cidr)))
        if number1~=number2 then
            return false
        else
            return true
        end
    end
end

-- Wrapper for IPMatch.
function BuiltInFunctions.IPMatchFunc(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.IPMatch(args[1], args[2])
end

-- GlobMatch determines whether key1 matches the pattern of key2 using glob pattern
function BuiltInFunctions.globMatch(key1, key2)
    if posix.fnmatch(key2, key1, posix.FNM_PATHNAME or posix.FNM_PERIOD) == 0 then
        return true
    else
        return false
    end
end

-- Wrapper for globMatch
function BuiltInFunctions.globMatchFunc(args)
    BuiltInFunctions.validateVariadicArgs(2, args)
    return BuiltInFunctions.globMatch(args[1], args[2])
end

-- GenerateGFunction is the factory method of the g(_, _) function.
function BuiltInFunctions.generateGFunction(rm)
    local function f(args)
        local name1 = args[1]
        local name2 = args[2]

        if not rm then
            return name1 == name2
        elseif #args==2 then
            return rm:hasLink(name1, name2)
        else
            local domain = args[3]
            return rm:hasLink(name1, name2, domain)
        end
    end

    return f
end

return BuiltInFunctions