/*
* Copyright 2020 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.
*/

#include "casbin/pch.h"

#ifndef ENFORCER_CPP
#define ENFORCER_CPP


#include <algorithm>

#include "casbin/enforcer.h"
#include "casbin/persist/watcher_ex.h"
#include "casbin/persist/file_adapter/file_adapter.h"
#include "casbin/persist/file_adapter/batch_file_adapter.h"
#include "casbin/rbac/default_role_manager.h"
#include "casbin/effect/default_effector.h"
#include "casbin/exception/casbin_adapter_exception.h"
#include "casbin/exception/casbin_enforcer_exception.h"
#include "casbin/util/util.h"

namespace casbin {

// enforce use a custom matcher to decides whether a "subject" can access a "object" 
// with the operation "action", input parameters are usually: (matcher, sub, obj, act), 
// use model matcher by default when matcher is "".
bool Enforcer::m_enforce(const std::string& matcher, std::shared_ptr<IEvaluator> evalator) {
    m_func_map.evalator = evalator;
    m_func_map.evalator->func_list.clear();
    m_func_map.LoadFunctionMap();

    if(!m_enabled)
        return true;

    std::string exp_string;
    if(matcher == "")
        exp_string = m_model->m["m"].assertion_map["m"]->value;
    else
        exp_string = matcher;


    // std::unordered_map<std::string, std::shared_ptr<RoleManager>> rm_map;
    bool ok = m_model->m.find("g") != m_model->m.end();

    if(ok) {
        for (auto [assertion_name, assertion] : m_model->m["g"].assertion_map) {
            std::shared_ptr<RoleManager>& rm = assertion->rm;

            if (dynamic_cast<DuktapeEvaluator*>(m_func_map.evalator.get()) != nullptr) {
                int char_count = static_cast<int>(std::count(assertion->value.begin(), assertion->value.end(), '_'));
                size_t index = exp_string.find(assertion_name + "(");

                if (index != std::string::npos)
                    exp_string.insert(index + assertion_name.length() + 1, "rm, ");

                m_func_map.evalator->LoadGFunction(rm, assertion_name, char_count + 1);
            } else {
                m_func_map.evalator->LoadGFunction(rm, assertion_name, 0);
            }

        }
    }

    // apply function map to current scope.
    // for(auto func : m_user_func_list)
    //     m_func_map.AddFunction(std::get<0>(func), std::get<1>(func), std::get<2>(func));

    bool hasEval = HasEval(exp_string);
    
    std::unordered_map<std::string, int> p_int_tokens;
    std::vector<std::string>& p_tokens = m_model->m["p"].assertion_map["p"]->tokens;
    p_int_tokens.reserve(p_tokens.size());

    for (int i = 0; i < p_tokens.size(); i++)
        p_int_tokens[p_tokens[i]] = i;

    std::vector<std::vector<std::string>>& p_policy = m_model->m["p"].assertion_map["p"]->policy;
    size_t policy_len = p_policy.size();

    std::vector<Effect> policy_effects(policy_len, Effect::Indeterminate);
    std::vector<float> matcher_results(policy_len, 0.0f);

    if(policy_len != 0) {
        // if(m_model->m["r"].assertion_map["r"]->tokens.size() != m_func_map.GetRLen())
        //     return false;

        //TODO
        for(int i = 0 ; i < policy_len ; i++) {
            std::vector<std::string>& p_vals = m_model->m["p"].assertion_map["p"]->policy[i];
            m_log.LogPrint("Policy Rule: ", p_vals);
            if(p_tokens.size() != p_vals.size())
                return false;
            m_func_map.evalator->Clean(m_model->m["p"]);
            m_func_map.evalator->InitialObject("p");
            for(int j = 0 ; j < p_tokens.size() ; j++) {
                size_t index = p_tokens[j].find("_");
                std::string token = p_tokens[j].substr(index + 1);
                m_func_map.evalator->PushObjectString("p", token, p_vals[j]);
            }

            if(hasEval) {
                auto ruleNames = GetEvalValue(exp_string);
                std::unordered_map<std::string, std::string> replacements;
                for(auto& ruleName: ruleNames) {
                    auto ruleNameCpy = EscapeAssertion(ruleName);

                    bool ok = p_int_tokens.find(ruleNameCpy) != p_int_tokens.end();
                    if (ok) {
                        int idx = p_int_tokens[ruleNameCpy];
                        replacements[ruleName] = p_vals[idx];
                    } else {
                        m_log.LogPrint("please make sure rule exists in policy when using eval() in matcher");
                        return false;
                    }
                }

                auto expWithRule = ReplaceEvalWithMap(exp_string, replacements);
                m_func_map.Evaluate(expWithRule);

            } else {

                m_func_map.Evaluate(exp_string);
            }

            //TODO
            // log.LogPrint("Result: ", result)
            if (m_func_map.evalator->CheckType() == Type::Bool) {
                bool result = m_func_map.evalator->GetBoolen();
                if (!result) {
                    policy_effects[i] = Effect::Indeterminate;
                    continue;
                }
            } else if (m_func_map.evalator->CheckType() == Type::Float){
                float result = m_func_map.evalator->GetFloat();
                if(result == 0.0) {
                    policy_effects[i] = Effect::Indeterminate;
                    continue;
                } else
                    matcher_results[i] = result;
            }
            else
                return false;

            bool is_p_eft = p_int_tokens.find("p_eft") != p_int_tokens.end();
            if(is_p_eft) {
                int j = p_int_tokens["p_eft"];
                std::string eft = p_vals[j];
                if(eft == "allow")
                    policy_effects[i] = Effect::Allow;
                else if(eft == "deny")
                    policy_effects[i] = Effect::Deny;
                else
                    policy_effects[i] = Effect::Indeterminate;
            }
            else
                policy_effects[i] = Effect::Allow;

            if(m_model->m["e"].assertion_map["e"]->value == "priority(p_eft) || deny")
                break;
        }
    } else {
        // Push initial value for p in symbol table
        // If p don't in symbol table, the evaluate result will be invalid.
        m_func_map.evalator->Clean(m_model->m["p"]);
        m_func_map.evalator->InitialObject("p");
        for(int j = 0 ; j < p_tokens.size() ; j++) {
            size_t index = p_tokens[j].find("_");
            std::string token = p_tokens[j].substr(index + 1);
            m_func_map.evalator->PushObjectString("p", token, "");
        }

        bool isvalid = m_func_map.Evaluate(exp_string);
        if (!isvalid) {
            return false;
        }
        bool result = m_func_map.evalator->GetBoolen();
        //TODO
        m_log.LogPrint("Result: ", result);
        if (result)
            policy_effects.push_back(Effect::Allow);
        else
            policy_effects.push_back(Effect::Indeterminate);
    }

    //TODO
    m_log.LogPrint("Rule Results: ", policy_effects);

    bool result = m_eft->MergeEffects(m_model->m["e"].assertion_map["e"]->value, policy_effects, matcher_results);

    return result;
}

/**
 * Enforcer is the default constructor.
 */
Enforcer ::Enforcer() {
}

/**
 * Enforcer initializes an enforcer with a model file and a policy file.
 *
 * @param model_path the path of the model file.
 * @param policyFile the path of the policy file.
 */
Enforcer ::Enforcer(const std::string& model_path, const std::string& policy_file)
    : Enforcer(model_path, std::make_shared<BatchFileAdapter>(policy_file)) {
}   

/**
 * Enforcer initializes an enforcer with a database adapter.
 *
 * @param model_path the path of the model file.
 * @param adapter the adapter.
 */
Enforcer ::Enforcer(const std::string& model_path, std::shared_ptr<Adapter> adapter)
    : Enforcer(std::make_shared<Model>(model_path), adapter) {
    m_model_path = model_path;
}

/**
 * Enforcer initializes an enforcer with a model and a database adapter.
 *
 * @param m the model.
 * @param adapter the adapter.
 */
Enforcer::Enforcer(const std::shared_ptr<Model>& m, std::shared_ptr<Adapter> adapter)
    : m_adapter(adapter), m_watcher(nullptr), m_model(m) {
    m_model->PrintModel();

    this->Initialize();

    if (m_adapter && m_adapter->file_path != "")
        this->LoadPolicy();
}

/**
 * Enforcer initializes an enforcer with a model.
 *
 * @param m the model.
 */
Enforcer::Enforcer(const std::shared_ptr<Model>& m) : Enforcer(m, NULL) {
}

/**
 * Enforcer initializes an enforcer with a model file.
 *
 * @param model_path the path of the model file.
 */
Enforcer ::Enforcer(const std::string& model_path): Enforcer(model_path, "") {
}

/**
 * Enforcer initializes an enforcer with a model file, a policy file and an enable log flag.
 *
 * @param model_path the path of the model file.
 * @param policyFile the path of the policy file.
 * @param enableLog whether to enable Casbin's log.
 */
Enforcer::Enforcer(const std::string& model_path, const std::string& policy_file, bool enable_log)
    : Enforcer(model_path, std::make_shared<BatchFileAdapter>(policy_file)) {
    this->EnableLog(enable_log);
}


// InitWithFile initializes an enforcer with a model file and a policy file.
void Enforcer::InitWithFile(const std::string& model_path, const std::string& policy_path) {
    std::shared_ptr<Adapter> a = std::make_shared<BatchFileAdapter>(policy_path);
    this->InitWithAdapter(model_path, a);
}

// InitWithAdapter initializes an enforcer with a database adapter.
void Enforcer::InitWithAdapter(const std::string& model_path, std::shared_ptr<Adapter> adapter) {
    std::shared_ptr<Model> m = Model::NewModelFromFile(model_path);

    this->InitWithModelAndAdapter(m, adapter);

    m_model_path = model_path;
}

// InitWithModelAndAdapter initializes an enforcer with a model and a database adapter.
void Enforcer::InitWithModelAndAdapter(const std::shared_ptr<Model>& m, std::shared_ptr<Adapter> adapter) {
    m_adapter = adapter;

    m_model = m;
    m_model->PrintModel();
    m_func_map.LoadFunctionMap();

    this->Initialize();

    // Do not initialize the full policy when using a filtered adapter
    if(m_adapter != NULL && !m_adapter->IsFiltered()) 
        this->LoadPolicy();
}

void Enforcer::Initialize() {
    this->rm = std::make_shared<DefaultRoleManager>(10);
    m_eft = std::make_shared<DefaultEffector>();
    m_watcher = nullptr;
    m_evalator = nullptr;

    m_enabled = true;
    m_auto_save = true;
    m_auto_build_role_links = true;
    m_auto_notify_watcher = true;
}

/**
 * Destructor of Enforcer
 * 
 * @step: Release the memory of Enforcer->m_scope
*/
Enforcer::~Enforcer() {}

// LoadModel reloads the model from the model CONF file.
// Because the policy is attached to a model, so the policy is invalidated and needs 
// to be reloaded by calling LoadPolicy().
void Enforcer::LoadModel() {
    m_model = Model::NewModelFromFile(m_model_path);

    m_model->PrintModel();
    m_func_map.LoadFunctionMap();

    this->Initialize();
}

// GetModel gets the current model.
std::shared_ptr<Model> Enforcer::GetModel() {
    return m_model;
}

// SetModel sets the current model.
void Enforcer::SetModel(const std::shared_ptr<Model>& m) {
    m_model = m;
    m_func_map.LoadFunctionMap();

    this->Initialize();
}

// GetAdapter gets the current adapter.
std::shared_ptr<Adapter> Enforcer::GetAdapter() {
    return m_adapter;
}

// SetAdapter sets the current adapter.
void Enforcer::SetAdapter(std::shared_ptr<Adapter> adapter) {
    m_adapter = adapter;
}

// SetWatcher sets the current watcher.
void Enforcer::SetWatcher(std::shared_ptr<Watcher> watcher) {
    m_watcher = watcher;
    auto func = [&, this](std::string str) {
        this->LoadPolicy();
    };
    watcher->SetUpdateCallback(func);
}

// GetRoleManager gets the current role manager.
std::shared_ptr<RoleManager> Enforcer ::GetRoleManager() {
    return this->rm;
}

// SetRoleManager sets the current role manager.
void Enforcer::SetRoleManager(std::shared_ptr<RoleManager>& rm) {
    this->rm = rm;
}

// SetEffector sets the current effector.
void Enforcer::SetEffector(std::shared_ptr<Effector> eft) {
    m_eft = eft;
}

// ClearPolicy clears all policy.
void Enforcer::ClearPolicy() {
    m_model->ClearPolicy();
}

// LoadPolicy reloads the policy from file/database.
void Enforcer::LoadPolicy() {
    this->ClearPolicy();
    m_adapter->LoadPolicy(m_model);
    m_model->PrintPolicy();

    if(m_auto_build_role_links) {
        this->BuildRoleLinks();
    }
}

//LoadFilteredPolicy reloads a filtered policy from file/database.
template<typename Filter>
void Enforcer::LoadFilteredPolicy(Filter filter) {
    this->ClearPolicy();

    std::shared_ptr<FilteredAdapter> filtered_adapter;

    if (m_adapter->IsFiltered())
        filtered_adapter = std::dynamic_pointer_cast<FilteredAdapter>(m_adapter);
    else
        throw CasbinAdapterException("filtered policies are not supported by this adapter");

    filtered_adapter->LoadFilteredPolicy(m_model, filter);

    m_model->PrintPolicy();
    if(m_auto_build_role_links)
        this->BuildRoleLinks();
}

// IsFiltered returns true if the loaded policy has been filtered.
bool Enforcer::IsFiltered() {
    return m_adapter->IsFiltered();
}

// SavePolicy saves the current policy (usually after changed with Casbin API) back to file/database.
void Enforcer::SavePolicy() {
    if(this->IsFiltered())
        throw CasbinEnforcerException("cannot save a filtered policy");

    m_adapter->SavePolicy(m_model);

    if(m_watcher != NULL){
        if (IsInstanceOf<WatcherEx>(m_watcher.get())) {
            auto watcher = dynamic_cast<WatcherEx*>(m_watcher.get());
            watcher->UpdateForSavePolicy(m_model);
        }
        else
            return m_watcher->Update();
    }
}

// EnableEnforce changes the enforcing state of Casbin, when Casbin is disabled, 
// all access will be allowed by the Enforce() function.
void Enforcer::EnableEnforce(bool enable) {
    m_enabled = enable;
}

// EnableLog changes whether Casbin will log messages to the Logger.
void Enforcer::EnableLog(bool enable) {
    m_log.GetLogger().EnableLog(enable);
}

// EnableAutoNotifyWatcher controls whether to save a policy rule automatically notify the Watcher when it is added or removed.
void Enforcer::EnableAutoNotifyWatcher(bool enable) {
    m_auto_notify_watcher = enable;
}

// EnableAutoSave controls whether to save a policy rule automatically to the adapter when it is added or removed.
void Enforcer::EnableAutoSave(bool auto_save) {
    m_auto_save = auto_save;
}

// EnableAutoBuildRoleLinks controls whether to rebuild the role inheritance relations when a role is added or deleted.
void Enforcer::EnableAutoBuildRoleLinks(bool auto_build_role_links) {
    m_auto_build_role_links = auto_build_role_links;
}

// BuildRoleLinks manually rebuild the role inheritance relations.
void Enforcer::BuildRoleLinks() {
    this->rm->Clear();

    m_model->BuildRoleLinks(this->rm);
}

// BuildIncrementalRoleLinks provides incremental build the role inheritance relations.
void Enforcer::BuildIncrementalRoleLinks(policy_op op, const std::string& p_type, const std::vector<std::vector<std::string>>& rules) {
    return m_model->BuildIncrementalRoleLinks(this->rm, op, "g", p_type, rules);
}

// Enforce decides whether a "subject" can access a "object" with the operation "action", 
// input parameters are usually: (sub, obj, act).
bool Enforcer::Enforce(std::shared_ptr<IEvaluator> evalator) {
    return this->EnforceWithMatcher("", evalator);
}

// Enforce with a vector param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforcer::Enforce(const DataList& params) {
    return this->EnforceWithMatcher("", params);
}

bool Enforcer::Enforce(const DataVector& params) {
    return this->EnforceWithMatcher("", params);
}

// Enforce with a map param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforcer::Enforce(const DataMap& params) {
    return this->EnforceWithMatcher("", params);
}

// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "".
bool Enforcer::EnforceWithMatcher(const std::string& matcher, std::shared_ptr<IEvaluator> evalator) {
    return m_enforce(matcher, evalator);
}

// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "".
bool Enforcer::EnforceWithMatcher(const std::string& matcher, const DataList& params) {
    const std::vector<std::string>& r_tokens = m_model->m["r"].assertion_map["r"]->tokens;

    size_t r_cnt = r_tokens.size();
    size_t cnt = params.size();

    if (cnt != r_cnt)
        return false;

    if (this->m_evalator == nullptr) {
        this->m_evalator = std::make_shared<DuktapeEvaluator>();
    }

    this->m_evalator->InitialObject("r");

    size_t i = 0;

    for(const Data& param : params) {
        if(const auto string_param = std::get_if<std::string>(&param)) {
            this->m_evalator->PushObjectString("r", r_tokens[i].substr(2, r_tokens[i].size() - 2), *string_param);
        } else if (const auto json_param = std::get_if<std::shared_ptr<nlohmann::json>>(&param)) {
            
            auto data_ptr = *json_param;
            std::string token_name = r_tokens[i].substr(2, r_tokens[i].size() - 2);
            this->m_evalator->PushObjectJson("r", token_name, *data_ptr);

        }
        ++i;
    }

    bool result = m_enforce(matcher, m_evalator);

    if (m_evalator != nullptr) {
        m_evalator->Clean(m_model->m["p"]);
        m_evalator->Clean(m_model->m["r"]);
    }

    return result;
}

// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "".
bool Enforcer::EnforceWithMatcher(const std::string& matcher, const DataVector& params) {
    const std::vector<std::string>& r_tokens = m_model->m["r"].assertion_map["r"]->tokens;

    size_t r_cnt = r_tokens.size();
    size_t cnt = params.size();

    if (cnt != r_cnt)
        return false;

    if (this->m_evalator == nullptr) {
        auto scope = InitializeScope();
        this->m_evalator = std::make_shared<DuktapeEvaluator>(scope);
    }

    this->m_evalator->InitialObject("r");

    size_t i = 0;

    for(const auto& param : params) {
        if(const auto string_param = std::get_if<std::string>(&param)) {
            this->m_evalator->PushObjectString("r", r_tokens[i].substr(2, r_tokens[i].size() - 2), *string_param);
        } else if (const auto json_param = std::get_if<std::shared_ptr<nlohmann::json>>(&param)) {
            
            auto data_ptr = *json_param;
            std::string token_name = r_tokens[i].substr(2, r_tokens[i].size() - 2);

            this->m_evalator->PushObjectJson("r", token_name, *data_ptr);
        }

        ++i;
    }

    bool result = m_enforce(matcher, m_evalator);

    if (m_evalator != nullptr) {
        m_evalator->Clean(m_model->m["p"]);
        m_evalator->Clean(m_model->m["r"]);
    }

    return result;
}

// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" 
// with the operation "action", input parameters are usually: (matcher, sub, obj, act), 
// use model matcher by default when matcher is "".
bool Enforcer::EnforceWithMatcher(const std::string& matcher, const DataMap& params) {
    if (this->m_evalator == nullptr) {
        auto scope = InitializeScope();
        this->m_evalator = std::make_shared<DuktapeEvaluator>(scope);
    }

    this->m_evalator->InitialObject("r");

    for (auto [param_name, param_data] : params) {
        if(const auto string_param = std::get_if<std::string>(&param_data)) {
            this->m_evalator->PushObjectString("r", param_name, *string_param);
        } else if (const auto json_param = std::get_if<std::shared_ptr<nlohmann::json>>(&param_data)) {
            
            auto data_ptr = *json_param;
            this->m_evalator->PushObjectJson("r", param_name, *data_ptr);
        }

    }

    bool result = m_enforce(matcher, m_evalator);

    if (m_evalator != nullptr) {
        m_evalator->Clean(m_model->m["p"]);
        m_evalator->Clean(m_model->m["r"]);
    }

    return result;
}

// BatchEnforce enforce in batches
std::vector<bool> Enforcer::BatchEnforce(const std::initializer_list<DataList>& requests) {
    // Initializing an array for storing results with false
    std::vector<bool> results;
    results.reserve(requests.size());
    for (const auto& request : requests) {
        results.push_back(this->Enforce(request));
    }
    return results;
}

// BatchEnforceWithMatcher enforce with matcher in batches
std::vector<bool> Enforcer::BatchEnforceWithMatcher(const std::string& matcher, const std::initializer_list<DataList>& requests) {
    std::vector<bool> results;
    results.reserve(requests.size());
    for (const auto& request : requests) {
        results.push_back(this->EnforceWithMatcher(matcher, request));
    }
    return results;
}

// clean scope to prepare next enforce
void Enforcer::clean_scope(std::string section_name) {

}

} // namespace casbin

#endif // ENFORCER_CPP
