/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.sdm.infrastructure;

import com.orientechnologies.common.exception.OException;
import com.orientechnologies.orient.core.db.ODatabase;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.metadata.security.ORole;
import com.orientechnologies.orient.core.metadata.security.ORule;
import com.orientechnologies.orient.core.metadata.security.OSecurity;
import com.orientechnologies.orient.core.metadata.security.OSecurityRole.ALLOW_MODES;
import com.orientechnologies.orient.core.metadata.security.OUser;

/**
 * Implementation of {@link DatabaseManager}.
 */
class DatabaseManagerImpl implements DatabaseManager {
    private final String url;

    private final String username;

    private final String password;

    /**
     * Constructor.
     *
     * @param url
     * @param username
     * @param password
     */
    public DatabaseManagerImpl(final String url, final String username,
            final String password) {
        this.url = url;
        this.username = username;
        this.password = password;
    }

    @Override
    public void createDatabase() throws OException {

		try (ODatabase<?> database = new ODatabaseDocumentTx(url, true)) {
			if (!database.exists()) {				
				database.create();				
				OSecurity security = database.getMetadata().getSecurity();
				saveRoleAndUser(security);
			}
		}
	}
        
    @Override
    public void dropDatabase() throws OException {

        ODatabase<?> database = new ODatabaseDocumentTx(url);
        if (database.exists()) {
            database.open(username, password);
            try {
                database.drop();
            } finally {
				if (!database.isClosed()) {
					database.close();
				}
            }
        }
    }

    @Override
    public ODatabaseDocument openDatabase() throws OException {
        ODatabaseDocument database = new ODatabaseDocumentTx(url, true);
        database.open(username, password);
        return database;
    }
    
    /**
     * saveRoleAndUser Save Role and User
     * 
     * @param security
     */
    private void saveRoleAndUser(OSecurity security) {
	
		ORole role = security.getRole(ORole.ADMIN);
		if (role == null) {
			role = security.createRole(ORole.ADMIN, ALLOW_MODES.ALLOW_ALL_BUT);
			role.addRule(ORule.ResourceGeneric.BYPASS_RESTRICTED, null, ORole.PERMISSION_ALL);
			role.save();
		}

		OUser user = security.getUser(username);
		if (user == null) {
			user = security.createUser(username, password, role);
		} else {
			user.setPassword(password);
			if (!user.hasRole(ORole.ADMIN, true)) {
				user.addRole(role);
			}
		}
		
		if (user!=null) {
			user.save();
		}
    }

}
