/*
 * 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 java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonReader;
import javax.json.JsonValue;

import com.orientechnologies.common.exception.OException;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.record.impl.ODocument;

/**
 * Fixture to manage the database in tests of repositories.
 */
public final class DatabaseFixture {
    private final DatabaseManagerFactory factory =
        new DatabaseManagerFactoryImpl();

    private final String url;

    private DatabaseManager databaseManager;

    /**
     * Constructor.
     *
     * @param databaseName
     */
    public DatabaseFixture(final Class<?> testClass) {
        url = "memory:" + testClass.getName();
    }

    /**
     * Creates documents from the specified resource. The content of the
     * resource must be a valid JSON array of JSON objects to be inserted into
     * the database.
     *
     * @param entityName
     *            the entity name
     * @param resource
     *            the resource
     * @return the document
     * @throws IOException
     *             I/O error occurred
     * @throws OException
     *             failed to save the document.
     */
    public void createDocuments(final String entityName,
            final URL resource) throws IOException, OException {
        JsonArray array;
        try (JsonReader reader =
            Json.createReader(new InputStreamReader(resource.openStream(),
                StandardCharsets.UTF_8))) {
            array = reader.readArray();
        }
        try (ODatabaseDocument database = databaseManager.openDatabase()) {
            for (JsonValue value : array) {
                ODocument document = new ODocument(entityName);
                document.fromJSON(value.toString());
                database.save(document);
            }
        }
    }

    /**
     * Returns the database manager.
     *
     * @return the database manager.
     */
    public DatabaseManager databaseManager() {
        return databaseManager;
    }

    /**
     * Creates a {@link DatabaseManager} instance and a database.
     *
     * @throws OException
     *             failed to setup.
     */
    public void setUp() throws OException {
        databaseManager = factory.newDatabaseManager(url);
        databaseManager.createDatabase();
    }

    /**
     * Drops the database and clear the {@link DatabaseManager} instance.
     *
     * @throws OException
     */
    public void tearDown() throws OException {
        databaseManager.dropDatabase();
        databaseManager = null;
    }
}
