/*
 * 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 <regex>

#include "casbin/effect/default_effector.h"
#include "casbin/enforcer.h"
#include "casbin/selected_policies.h"
#include "casbin/exception/casbin_adapter_exception.h"
#include "casbin/exception/casbin_enforcer_exception.h"
#include "casbin/persist/file_adapter/batch_file_adapter.h"
#include "casbin/persist/file_adapter/file_adapter.h"
#include "casbin/persist/watcher_ex.h"
#include "casbin/model/policy_collection.hpp"
#include "casbin/rbac/default_role_manager.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::vector<std::string>& explains, std::shared_ptr<IEvaluator> evalator) {
    if (!explains.empty()) {
        explains.clear();
    }

    // when Casbin is disabled, all access will be allowed by the m_enforce()
    if (!m_enabled) {
        return true;
    }

    evalator->func_list.clear();
    evalator->LoadFunctions();

    // std::unordered_map<std::string, std::shared_ptr<RoleManager>> rm_map;
    if (m_model->m.find("g") != m_model->m.end()) {
        for (auto [assertion_name, assertion] : m_model->m["g"].assertion_map) {
            std::shared_ptr<RoleManager>& rm = assertion->rm;

            int char_count = static_cast<int>(std::count(assertion->value.begin(), assertion->value.end(), '_'));
            evalator->LoadGFunction(rm, assertion_name, char_count);
        }
    }

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

    std::unordered_map<std::string, int> r_int_tokens;
    const std::vector<std::string>& r_tokens = m_model->m["r"].assertion_map["r"]->tokens;
    r_int_tokens.reserve(r_tokens.size());

    for (int i = 0; i < r_tokens.size(); i++) {
        r_int_tokens[r_tokens[i]] = i;
    }

    std::unordered_map<std::string, int> p_int_tokens;
    const 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;
    }

    bool hasEval = HasEval(exp_string);

    std::vector<Effect> policy_effects;
    std::vector<float> matcher_results;

    Effect effect;
    int explainIndex;

    SelectedPolicies selected_policies(evalator, matcher, m_model);
    PoliciesValues& p_policy = *selected_policies;

    if (auto policy_len = p_policy.size(); policy_len != 0) {
        policy_effects = std::vector<Effect>(policy_len, Effect::Indeterminate);
        matcher_results = std::vector<float>(policy_len, 0.0f);

        int policy_index = 0;
        for (auto& p_vals : p_policy ) {
            casbin::LogUtil::LogPrint("Policy Rule: ", p_vals);
            if (p_tokens.size() != p_vals.size()) {
                throw CasbinEnforcerException("invalid policy size");
                //  m_log.LogPrintf("invalid policy size: expected ", p_tokens.size(), ", got ",p_vals.size());
                //  return false;
            }

            evalator->Clean(m_model->m["p"], false);
            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);
                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 {
                        throw CasbinEnforcerException("please make sure rule exists in policy when using eval() in matcher");
                        // return false;
                    }
                }

                auto expWithRule = ReplaceEvalWithMap(exp_string, replacements);
                evalator->Eval(expWithRule);

            } else {
                evalator->Eval(exp_string);
            }

            // set to no-match at first
            matcher_results[policy_index] = 0;
            if (evalator->CheckType() == Type::Bool) {
                bool result = evalator->GetBoolean();
                if (result) {
                    matcher_results[policy_index] = 1;
                }
            } else if (evalator->CheckType() == Type::Float) {
                float result = evalator->GetFloat();
                if (result != 0.0) {
                    matcher_results[policy_index] = 1;
                }
            } else {
                throw CasbinEnforcerException("matcher result should be bool, int or float");
                // return false;
            }

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

            effect = m_eft->MergeEffects(m_model->m["e"].assertion_map["e"]->value, policy_effects,
                                         matcher_results, policy_index, policy_len, explainIndex);

            if (effect != Effect::Indeterminate) {
                break;
            }
            policy_index++;
        }

        casbin::LogUtil::LogPrint("Rule Results: ", policy_effects);
    } else {
        if (hasEval && p_policy.empty()) {
            throw CasbinEnforcerException("please make sure rule exists in policy when using eval() in matcher");
            // return false;
        }

        policy_effects = std::vector<Effect>(1, Effect::Indeterminate);
        matcher_results = std::vector<float>(1, 1);

        // Push initial value for p in symbol table
        // If p don't in symbol table, the evaluate result will be invalid.
        evalator->Clean(m_model->m["p"], false);
        evalator->InitialObject("p");
        for (const auto& p_token : p_tokens) {
            size_t index = p_token.find("_");
            std::string token = p_token.substr(index + 1);
            evalator->PushObjectString("p", token, "");
        }

        bool isvalid = evalator->Eval(exp_string);
        if (!isvalid) {
            return false;
        }
        bool result = evalator->GetBoolean();

        if (result) {
            policy_effects[0] = Effect::Allow;
        } else {
            policy_effects[0] = Effect::Indeterminate;
        }

        effect = m_eft->MergeEffects(m_model->m["e"].assertion_map["e"]->value, policy_effects,
                                     matcher_results, 0, 1, explainIndex);

        casbin::LogUtil::LogPrint("Rule Results: ", policy_effects);
    }

    PoliciesValues logExplains;

    logExplains.emplace(explains);
    if (explainIndex != -1 && (p_policy.size() > explainIndex)) {
        explains = *std::next(p_policy.begin(), explainIndex);
        logExplains.emplace(explains);
    }

    // effect --> result
    bool result = false;
    if (effect == Effect::Allow) {
        result = true;
    }

    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->IsValid())
        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();

    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();

    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;

    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);
}

// SetWatcher sets the current evaluator.
void Enforcer::SetEvaluator(std::shared_ptr<IEvaluator> evaluator) {
    this->m_evalator = evaluator;
}

// 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() {
    // must use base's LoadPolicy to avoid dead lock
    Enforcer::ClearPolicy();
    m_adapter->LoadPolicy(m_model);
    m_model->PrintPolicy();

    if (m_auto_build_role_links) {
        Enforcer::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 PoliciesValues& 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) {
    std::vector<std::string> explain;
    bool result = EnforceExWithMatcher(matcher, evalator, explain);
    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 DataList& params) {
    std::vector<std::string> explain;
    bool result = EnforceExWithMatcher(matcher, params, explain);
    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) {
    std::vector<std::string> explain;
    bool result = EnforceExWithMatcher(matcher, params, explain);
    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) {
    std::vector<std::string> explain;
    bool result = EnforceExWithMatcher(matcher, params, explain);
    return result;
}

bool Enforcer::EnforceEx(std::shared_ptr<IEvaluator> evalator, std::vector<std::string>& explain) {
    return this->EnforceExWithMatcher("", evalator, explain);
}

bool Enforcer::EnforceEx(const DataList& params, std::vector<std::string>& explain) {
    return this->EnforceExWithMatcher("", params, explain);
}

bool Enforcer::EnforceEx(const DataVector& params, std::vector<std::string>& explain) {
    return this->EnforceExWithMatcher("", params, explain);
}

bool Enforcer::EnforceEx(const DataMap& params, std::vector<std::string>& explain) {
    return this->EnforceExWithMatcher("", params, explain);
}

bool Enforcer::EnforceExWithMatcher(const std::string& matcher, std::shared_ptr<IEvaluator> evalator, std::vector<std::string>& explain) {
    return m_enforce(matcher, explain, evalator);
}

bool Enforcer::EnforceExWithMatcher(const std::string& matcher, const DataList& params, std::vector<std::string>& explain) {
    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<ExprtkEvaluator>();
    }

    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, explain, m_evalator);

    return result;
}

bool Enforcer::EnforceExWithMatcher(const std::string& matcher, const DataVector& params, std::vector<std::string>& explain) {
    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<ExprtkEvaluator>();
    }

    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, explain, m_evalator);

    return result;
}
bool Enforcer::EnforceExWithMatcher(const std::string& matcher, const DataMap& params, std::vector<std::string>& explain) {
    if (this->m_evalator == nullptr) {
        this->m_evalator = std::make_shared<ExprtkEvaluator>();
    }

    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, explain, m_evalator);

    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;
}

} // namespace casbin

#endif // ENFORCER_CPP
