/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.rya.api.client.mongo;

import static org.apache.rya.mongodb.instance.MongoRyaInstanceDetailsRepository.INSTANCE_DETAILS_COLLECTION_NAME;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import org.apache.rya.api.client.Install;
import org.apache.rya.api.client.Install.DuplicateInstanceNameException;
import org.apache.rya.api.client.Install.InstallConfiguration;
import org.apache.rya.api.client.InstanceExists;
import org.apache.rya.api.client.RyaClient;
import org.apache.rya.api.client.RyaClientException;
import org.apache.rya.mongodb.MongoITBase;
import org.junit.Test;

/**
 * Integration tests the methods of {@link MongoInstall}.
 */
public class MongoInstallIT extends MongoITBase {

    @Test
    public void install() throws DuplicateInstanceNameException, RyaClientException {
        // Install an instance of Rya.
        final String ryaInstance = conf.getMongoDBName();

        // Setup the connection details that were used for the embedded Mongo DB instance we are testing with.
        final MongoConnectionDetails connectionDetails = getConnectionDetails();

        // Check that the instance does not exist.
        final InstanceExists instanceExists = new MongoInstanceExists(getMongoClient());
        assertFalse(instanceExists.exists(ryaInstance));

        // Install an instance of Rya with all the valid options turned on.
        final InstallConfiguration installConfig = InstallConfiguration.builder()
                .setEnableTableHashPrefix(true)
                .setEnableFreeTextIndex(true)
                .setEnableTemporalIndex(true)
                .build();

        final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient());
        final Install install = ryaClient.getInstall();
        install.install(ryaInstance, installConfig);

        // Check that the instance exists.
        assertTrue(instanceExists.exists(ryaInstance));

        // Show that the expected collections were created within the database.
        final List<String> expected = Arrays.asList(INSTANCE_DETAILS_COLLECTION_NAME, "rya_triples");
        int count = 0;
        final List<String> found = new ArrayList<>();
        for (final String collection : getMongoClient().getDatabase(conf.getMongoDBName()).listCollectionNames()) {
            count += expected.contains(collection) ? 1 : 0;
            found.add( collection );
        }
        assertTrue("Tables missing from:" + expected + " actual:" + found, expected.size() == count);
        assertTrue("Instance should exist.", instanceExists.exists(ryaInstance));
    }

    @Test
    public void install_withAllIndexers() throws DuplicateInstanceNameException, RyaClientException {
        // Install an instance of Rya.
        final String ryaInstance = conf.getMongoDBName();

        // Setup the connection details that were used for the embedded Mongo DB instance we are testing with.
        final MongoConnectionDetails connectionDetails = getConnectionDetails();

        // Check that the instance does not exist.
        final InstanceExists instanceExists = new MongoInstanceExists(getMongoClient());
        assertFalse(instanceExists.exists(ryaInstance));

        // Install an instance of Rya with all the valid options turned on.
        final InstallConfiguration installConfig = InstallConfiguration.builder()
                .setEnableTableHashPrefix(true)
                .setEnableFreeTextIndex(true)
                .setEnableTemporalIndex(true)
                .setEnableEntityCentricIndex(true)
                .setEnableGeoIndex(true)
                .setEnablePcjIndex(true)
                .build();

        final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient());
        final Install install = ryaClient.getInstall();
        install.install(ryaInstance, installConfig);

        // Check that the instance exists.
        assertTrue(instanceExists.exists(ryaInstance));

        // Show that the expected collections were created within the database.
        final List<String> expected = Arrays.asList(INSTANCE_DETAILS_COLLECTION_NAME, "rya_triples");
        int count = 0;
        final List<String> found = new ArrayList<>();
        for (final String collection : getMongoClient().getDatabase(conf.getMongoDBName()).listCollectionNames()) {
            count += expected.contains(collection) ? 1 : 0;
            found.add( collection );
        }
        assertTrue("Tables missing from:" + expected + " actual:" + found, expected.size() == count);
        assertTrue("Instance should exist.", instanceExists.exists(ryaInstance));
    }

    @Test(expected = DuplicateInstanceNameException.class)
    public void install_alreadyExists() throws DuplicateInstanceNameException, RyaClientException {
        // Install an instance of Rya.
        final String instanceName = conf.getRyaInstanceName();
        final InstallConfiguration installConfig = InstallConfiguration.builder().build();

        final MongoConnectionDetails connectionDetails = getConnectionDetails();

        final RyaClient ryaClient = MongoRyaClientFactory.build(connectionDetails, getMongoClient());
        final Install install = ryaClient.getInstall();
        install.install(instanceName, installConfig);

        // Install it again throws expected error.
        install.install(instanceName, installConfig);
    }

    private MongoConnectionDetails getConnectionDetails() {
        final Optional<char[]> password = conf.getMongoPassword() != null ?
                Optional.of(conf.getMongoPassword().toCharArray()) :
                    Optional.empty();

                return new MongoConnectionDetails(
                        conf.getMongoHostname(),
                        Integer.parseInt(conf.getMongoPort()),
                        Optional.ofNullable(conf.getMongoUser()),
                        password);
    }
}