#include "users_utils.h"
#include <saas/deploy_manager/server/client/client.h>

namespace NRTYDeploy {
    NDMInterface::TUser GetUser(IVersionedStorage& storage, const TString& login) {
        NDMInterface::TUser result;
        if (!storage.ExistsNode("/users")) {
            result.SetDefaultRole(NDMInterface::TUser::SUPER_USER);
            result.SetLogin(login);
        } else {
            try {
                storage.GetValue("/users/" + login, result);
            } catch (const yexception& e) {
                if (login == "guest")
                    ythrow TCodedException(500) << "cannot load guest user: " << e.what();
                return GetUser(storage, "guest");
            }
        }
        return result;
    }

    void ListUsers(IVersionedStorage& storage, TVector<TString>& result) {
        if (!storage.GetNodes("/users", result))
            ythrow TCodedException(500) << "cannot list users";
    }

    void SetProjectUser(NDMInterface::TProject& project, const TString& user, NDMInterface::TUser::TRole role) {
        if (role != NDMInterface::TUser::NOT_ALLOWED) {
            NDMInterface::TProject::TProjectUser& prUser = *project.AddUsers();
            prUser.SetLogin(user);
            prUser.SetRole(role);
        }
    }

    void FillProjectUsers(IVersionedStorage& storage, NDMInterface::TProject& project) {
        project.ClearUsers();
        TVector<TString> users;
        storage.GetNodes("/users", users);
        for (const auto& user : users) {
            try {
                if (user == "guest")
                    continue;
                NDMInterface::TUser loadedUser = GetUser(storage, user);
                bool set = false;
                for (const auto& rInP : loadedUser.GetRoleInProject()) {
                    if (rInP.GetProject() == project.GetName()) {
                        SetProjectUser(project, user, rInP.GetRole());
                        set = true;
                        break;
                    }
                }
                if (!set)
                    SetProjectUser(project, user, loadedUser.GetDefaultRole());
            } catch (...)  {
            }
        }
    }

    void SaveUser(IVersionedStorage& storage, const NDMInterface::TUser& user) {
        storage.SetValue("/users/" + user.GetLogin(), user);
    }

    NDMInterface::TUser::TRole GetUserRoleInProject(IVersionedStorage& storage, const TString& login, const TString& project) {
        const NDMInterface::TUser user = GetUser(storage, login);
        for (const auto& prj : user.GetRoleInProject())
            if (prj.GetProject() == project)
                return prj.GetRole();
        return user.GetDefaultRole();
    }
}
