/*
 * 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 static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

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.ResourceGeneric;
import com.orientechnologies.orient.core.metadata.security.OSecurity;
import com.orientechnologies.orient.core.metadata.security.OUser;

/**
 * Tests of {@link DatabaseManagerImpl}.
 */
public class DatabaseManagerImplTest {
    private static final String URL =
        "memory:" + DatabaseManagerImpl.class.getName();

    private static final String USERNAME = "username";

    private static final String PASSWORD = "password";

    private DatabaseManagerImpl manager;

    @Before
    public void setUp() {
        manager = new DatabaseManagerImpl(URL, USERNAME, PASSWORD);
    }

    @After
    public void tearDown() {
        ODatabase<?> database = new ODatabaseDocumentTx(URL);
        if (database.exists()) {
            database.open(OUser.ADMIN, OUser.ADMIN);
            try {
                database.drop();
            } finally {
                if (!database.isClosed()) {
                    database.close();
                }
            }
        }
    }

    @Test
    public void testCreateDatabase() {
        manager.createDatabase();
        ODatabase<?> database = new ODatabaseDocumentTx(URL);
        assertTrue(database.exists());
        database.open(USERNAME, PASSWORD);
        try {
            OSecurity security = database.getMetadata().getSecurity();
            ORole role = security.getRole(ORole.ADMIN);
            assertTrue(role.allow(ResourceGeneric.BYPASS_RESTRICTED, null,
                ORole.PERMISSION_ALL));
            OUser user = security.getUser(USERNAME);
            assertTrue(user.checkPassword(PASSWORD));
            assertTrue(user.getRoles().contains(role));
        } finally {
            database.close();
        }
    }

    @Test
    public void testCreateDatabaseExisting() {
        ODatabase<?> database = new ODatabaseDocumentTx(URL);
        database.create();
        database.close();

        manager.createDatabase();

        database = new ODatabaseDocumentTx(URL);
        database.open(OUser.ADMIN, OUser.ADMIN);
        try {
            assertNull(
                database.getMetadata().getSecurity().getUser(USERNAME));
        } finally {
            database.close();
        }
    }

    @Test
    public void testDropDatabase() {
        manager.createDatabase();
        manager.dropDatabase();
        ODatabase<?> database = new ODatabaseDocumentTx(URL);
        try {
            assertFalse(database.exists());
        } finally {
            database.close();
        }
    }

    @Test
    public void testDropDatabaseNonExisting() {
        manager.dropDatabase();
    }

    @Test
    public void testOpenDatabase() {
        manager.createDatabase();
        try (ODatabaseDocument database = manager.openDatabase()) {
            assertNotNull(
                database.getMetadata().getSecurity().getUser(USERNAME));
        }
    }
}
