RoleDialog::RoleDialog(
        const repo::core::model::RepoRole &role,
        const repo::core::model::RepoRoleSettings &settings,
        const QString &currentDatabase,
        const std::map<std::string, std::list<std::string> > &databasesWithProjects,
        const bool isCopy,
        QWidget *parent)
    : QDialog(parent)
    , oldRole(role)
    , settings(settings)
    , databasesWithProjects(databasesWithProjects)
    , ui(new Ui::RoleDialog)
    , rwSeparatedEntries(repo::gui::primitive::RepoComboBoxEditor::getSeparatedEntries({
    tr("Read (Cannot comment)").toStdString(),
    tr("Read (Can comment)").toStdString(),
	tr("ReadWrite").toStdString() }))
{
	
    ui->setupUi(this);



    //--------------------------------------------------------------------------
    // Permissions
    ui->permissionsUnfilterableTree->setHeaders({tr("Project"), tr("Permission")});
    ui->permissionsUnfilterableTree->registerTabWidget(ui->tabWidget, (int)Tab::PERMISSIONS);
    QHash<QString, repo::gui::primitive::RepoComboBoxDelegate *> permissionsDelegates;
    for (std::pair<std::string, std::list<std::string> > pair : databasesWithProjects)
    {
        QList<repo::gui::primitive::RepoComboBoxEditor::SeparatedEntries> rwSEList =
        { repo::gui::primitive::RepoComboBoxEditor::getSeparatedEntries(pair.second),
          rwSeparatedEntries};
        permissionsDelegates.insert(
                    QString::fromStdString(pair.first),
                    new repo::gui::primitive::RepoComboBoxDelegate(rwSEList));
    }
    ui->permissionsUnfilterableTree->setDelegates(permissionsDelegates);
    for (repo::core::model::RepoPermission p : role.getProjectAccessRights())
    {
        ui->permissionsUnfilterableTree->addRow(
                    QString::fromStdString(p.project),
                    accessRightToString(p.permission));
    }
    QObject::connect(ui->databaseComboBox, &QComboBox::currentTextChanged,
                     this, &RoleDialog::setDelegate);


    //--------------------------------------------------------------------------
    // Set database combo box
    for (auto entry : databasesWithProjects)
    {
        ui->databaseComboBox->addItem(QString::fromStdString(entry.first));
    }

    //--------------------------------------------------------------------------
    // Set name
    if (!role.isEmpty())
    {
        QString roleName = QString::fromStdString(role.getName());
        if (isCopy)
            roleName += " " + tr("(Copy)");
        ui->nameLineEdit->setText(roleName);
        ui->roleNameGroupBox->setChecked(isCopy && !role.isEmpty());

        // Set database
        ui->databaseComboBox->setCurrentText(
                    role.getDatabase().empty()
                    ? currentDatabase
                    : QString::fromStdString(role.getDatabase()));
    }

    //--------------------------------------------------------------------------
    // Settings
    // Color
    ui->colorLineEdit->addAction(QIcon(), QLineEdit::TrailingPosition);
    QObject::connect(ui->colorLineEdit->actions()[0], &QAction::triggered,
            this, &RoleDialog::showColorDialog);
    setColor(QString::fromStdString(settings.getColor()));


    // Description
    ui->descriptionPlainTextEdit->setPlainText(QString::fromStdString(settings.getDescription()));


    //--------------------------------------------------------------------------
    // Privileges
    ui->privilegesUnfilterableTree->setHeaders({
                                                   tr("Database"),
                                                   tr("Collection"),
                                                   tr("Actions")});
    ui->privilegesUnfilterableTree->registerTabWidget(ui->tabWidget, (int)Tab::PRIVILEGES);
    ui->privilegesUnfilterableTree->setButtonsEnabled(false);
    for (repo::core::model::RepoPrivilege p : role.getPrivileges())
    {
        QString qactions;
        for (std::string action : repo::core::model::RepoRole::dbActionsToStrings(p.actions))
        {
            qactions += QString::fromStdString(action) + ", ";
        }
        qactions.remove(qactions.size()-2, 2); // remove last comma

        QStringList qlist = {
            QString::fromStdString(p.database),
            QString::fromStdString(p.collection),
            qactions
        };
        ui->privilegesUnfilterableTree->addRow(qlist, false);
    }

    //--------------------------------------------------------------------------
    // Inherited Roles
    ui->inheritedRolesUnfilterableTree->setHeaders({tr("Database"), tr("Role")});
    ui->inheritedRolesUnfilterableTree->registerTabWidget(ui->tabWidget, (int)Tab::INHERITED_ROLES);
    ui->inheritedRolesUnfilterableTree->setButtonsEnabled(false);
    for (std::pair<std::string, std::string> pair : role.getInheritedRoles())
    {
        ui->inheritedRolesUnfilterableTree->addRow(pair, false);
    }

    //--------------------------------------------------------------------------
    // Modules
    ui->modulesUnfilterableTree->setHeaders({tr("Module")});
    ui->modulesUnfilterableTree->registerTabWidget(ui->tabWidget, (int)Tab::MODULES);
    ui->modulesUnfilterableTree->setNewRowText({tr("<module>")});
    for (std::string module : settings.getModules())
    {
        ui->modulesUnfilterableTree->addRow({QString::fromStdString(module)});
    }

    //--------------------------------------------------------------------------
    // Connect buttons
    QObject::connect(
                ui->colorPickerPushButton, &QPushButton::pressed,
                this, &RoleDialog::showColorDialog);

    QObject::connect(
                ui->colorLineEdit, &QLineEdit::textEdited,
                this, &RoleDialog::setColor);
}
bool MongoDatabaseHandler::performRoleCmd(
	const OPERATION                         &op,
	const repo::core::model::RepoRole       &role,
	std::string                             &errMsg)
{
	bool success = true;
	mongo::DBClientBase *worker;

	if (!role.isEmpty())
	{
		if (role.getName().empty() || role.getDatabase().empty())
		{
			errMsg += "Role bson does not contain role name/database name";
		}
		else{
			try{
				worker = workerPool->getWorker();
				mongo::BSONObjBuilder cmdBuilder;
				std::string roleName = role.getName();
				switch (op)
				{
				case OPERATION::INSERT:
					cmdBuilder << "createRole" << roleName;
					break;
				case OPERATION::UPDATE:
					cmdBuilder << "updateRole" << roleName;
					break;
				case OPERATION::DROP:
					cmdBuilder << "dropRole" << roleName;
				}

				if (op != OPERATION::DROP)
				{

					repo::core::model::RepoBSON privileges = role.getObjectField(REPO_ROLE_LABEL_PRIVILEGES);
					cmdBuilder.appendArray("privileges", privileges);

					repo::core::model::RepoBSON inheritedRoles = role.getObjectField(REPO_ROLE_LABEL_INHERITED_ROLES);

					cmdBuilder.appendArray("roles", inheritedRoles);
				}


				mongo::BSONObj info;
				auto cmd = cmdBuilder.obj();
				worker->runCommand(role.getDatabase(), cmd, info);

				repoTrace << "Role command : " << cmd;

				std::string cmdError = info.getStringField("errmsg");
				if (!cmdError.empty())
				{
					success = false;
					errMsg += cmdError;
				}

			}
			catch (mongo::DBException &e)
			{
				success = false;
				std::string errString(e.what());
				errMsg += errString;
			}

			workerPool->returnWorker(worker);
		}
		
	}
	else
	{
		errMsg += "Role bson is empty";
	}


	return success;
}