/**
 * 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 java.util.Objects.requireNonNull;

import java.util.Date;

import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.rya.api.client.Install;
import org.apache.rya.api.client.InstanceExists;
import org.apache.rya.api.client.RyaClientException;
import org.apache.rya.api.instance.RyaDetails;
import org.apache.rya.api.instance.RyaDetails.EntityCentricIndexDetails;
import org.apache.rya.api.instance.RyaDetails.FreeTextIndexDetails;
import org.apache.rya.api.instance.RyaDetails.JoinSelectivityDetails;
import org.apache.rya.api.instance.RyaDetails.PCJIndexDetails;
import org.apache.rya.api.instance.RyaDetails.ProspectorDetails;
import org.apache.rya.api.instance.RyaDetails.TemporalIndexDetails;
import org.apache.rya.api.instance.RyaDetailsRepository;
import org.apache.rya.api.instance.RyaDetailsRepository.AlreadyInitializedException;
import org.apache.rya.api.instance.RyaDetailsRepository.RyaDetailsRepositoryException;
import org.apache.rya.api.persist.RyaDAOException;
import org.apache.rya.indexing.accumulo.ConfigUtils;
import org.apache.rya.mongodb.MongoDBRdfConfiguration;
import org.apache.rya.mongodb.instance.MongoRyaInstanceDetailsRepository;
import org.apache.rya.rdftriplestore.inference.InferenceEngineException;
import org.apache.rya.sail.config.RyaSailFactory;
import org.eclipse.rdf4j.sail.Sail;
import org.eclipse.rdf4j.sail.SailException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Optional;
import com.mongodb.MongoClient;

import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
 * An Mongo implementation of the {@link Install} command.
 * </p>
 * Notes about the scheme:
 * <ul>
 *   <li>The Rya instance name is used as the DB name in Mongo.</li>
 *   <li>The Rya triples, instance details, and Rya indexes each get their own collection.</li>
 *   <li>Each Mongo DB can have only one Rya instance.</li>
 * </ul>
 */
@DefaultAnnotation(NonNull.class)
public class MongoInstall implements Install {

    private static final Logger log = LoggerFactory.getLogger(MongoInstall.class);

    private final MongoConnectionDetails connectionDetails;
    private final MongoClient adminClient;
    private final InstanceExists instanceExists;

    /**
     * Constructs an instance of {@link MongoInstall}.
     *
     * @param connectionDetails - Details to connect to the server. (not null)
     * @param adminClient - Provides programmatic access to the instance of Mongo that hosts Rya instances. (not null)
     * @param instanceExists - The interactor used to check if a Rya instance exists. (not null)
     */
    public MongoInstall(
            final MongoConnectionDetails connectionDetails,
            final MongoClient adminClient,
            final MongoInstanceExists instanceExists) {
        this.connectionDetails = requireNonNull(connectionDetails);
        this.adminClient = requireNonNull(adminClient);
        this.instanceExists = requireNonNull(instanceExists);
    }

    @Override
    public void install(final String instanceName, final InstallConfiguration installConfig) throws DuplicateInstanceNameException, RyaClientException {
        requireNonNull(instanceName);
        requireNonNull(installConfig);

        // Check to see if a Rya instance has already been installed with this name.
        if (instanceExists.exists(instanceName)) {
            throw new DuplicateInstanceNameException("An instance of Rya has already been installed to this Rya storage " + "with the name '" + instanceName + "'. Try again with a different name.");
        }

        // Initialize the Rya Details table.
        final RyaDetails ryaDetails;
        try {
            ryaDetails = initializeRyaDetails(instanceName, installConfig);
        } catch (final AlreadyInitializedException e) {
            // This can only happen if somebody else installs an instance of Rya with the name between the check and now.
            throw new DuplicateInstanceNameException(
                    "An instance of Rya has already been installed to this Rya storage " +
                            "with the name '" + instanceName + "'. Try again with a different name.");
        } catch (final RyaDetailsRepositoryException e) {
            throw new RyaClientException("The RyaDetails couldn't be initialized. Details: " + e.getMessage(), e);
        }

        // Initialize the rest of the collections used by the Rya instance.
        final MongoDBRdfConfiguration ryaConfig = makeRyaConfig(connectionDetails, ryaDetails);
        try {
            final Sail ryaSail = RyaSailFactory.getInstance(ryaConfig);
            ryaSail.shutDown();
        } catch (final AccumuloException | AccumuloSecurityException | RyaDAOException | InferenceEngineException e) {
            throw new RyaClientException("Could not initialize all of the tables for the new Rya instance. " +
                    "This instance may be left in a bad state.", e);
        } catch (final SailException e) {
            throw new RyaClientException("Problem shutting down the Sail object used to install Rya.", e);
        }
    }

    /**
     * @return The version of the application as reported by the manifest.
     */
    private String getVersion() {
        return "" + this.getClass().getPackage().getImplementationVersion();
    }

    /**
     * Initializes the {@link RyaDetails} and stores them for the new instance.
     *
     * @param instanceName - The name of the instance that is being created. (not null)
     * @param installConfig - The instance's install configuration. (not null)
     * @return The {@link RyaDetails} that were stored.
     * @throws AlreadyInitializedException Could not be initialized because a table with this instance name has already
     *   exists and is holding the details.
     * @throws RyaDetailsRepositoryException Something caused the initialization operation to fail.
     */
    private RyaDetails initializeRyaDetails(
            final String instanceName,
            final InstallConfiguration installConfig) throws AlreadyInitializedException, RyaDetailsRepositoryException {
        final RyaDetailsRepository detailsRepo = new MongoRyaInstanceDetailsRepository(adminClient, instanceName);

        if(installConfig.getFluoPcjAppName().isPresent()) {
        	log.warn("Mongo does not have fluo support, use ignoring the configured fluo application name: " + installConfig.getFluoPcjAppName().get());
        }
        
        // Build the PCJ Index details.
        final PCJIndexDetails.Builder pcjDetailsBuilder = PCJIndexDetails.builder()
                .setEnabled(installConfig.isPcjIndexEnabled());

        final RyaDetails details = RyaDetails.builder()
                // General Metadata
                .setRyaInstanceName(instanceName).setRyaVersion(getVersion())

                // Secondary Index Values
                // FIXME RYA-215 .setGeoIndexDetails(new GeoIndexDetails(installConfig.isGeoIndexEnabled()))
                .setTemporalIndexDetails(new TemporalIndexDetails(installConfig.isTemporalIndexEnabled()))
                .setFreeTextDetails(new FreeTextIndexDetails(installConfig.isFreeTextIndexEnabled()))
                .setEntityCentricIndexDetails(new EntityCentricIndexDetails(false))
                .setPCJIndexDetails(pcjDetailsBuilder)

                // Statistics values.
                .setProspectorDetails(new ProspectorDetails(Optional.<Date> absent()))
                .setJoinSelectivityDetails(new JoinSelectivityDetails(Optional.<Date> absent()))
                .build();

        // Initialize the table.
        detailsRepo.initialize(details);

        return details;
    }

    /**
     * Builds a {@link MongoRdfConfiguration} object that will be used by the
     * Rya DAO to initialize all of the tables it will need.
     *
     * @param connectionDetails - Indicates how to connect to Mongo. (not null)
     * @param ryaDetails - Indicates what needs to be installed. (not null)
     * @return A Rya Configuration object that can be used to perform the install.
     */
    private static MongoDBRdfConfiguration makeRyaConfig(
            final MongoConnectionDetails connectionDetails,
            final RyaDetails ryaDetails) {
        // Start with a configuration that is built using the connection details.

        final MongoDBRdfConfiguration conf = connectionDetails.build(ryaDetails.getRyaInstanceName());

        conf.setBoolean(ConfigUtils.USE_PCJ, ryaDetails.getPCJIndexDetails().isEnabled());

        // Mongo does not support entity indexing.
        if(ryaDetails.getEntityCentricIndexDetails().isEnabled()) {
            log.warn("The install configuration says to enable Entity Centric indexing, but Mongo RYA does not support " +
                    "that feature. Ignoring this configuration.");
        }

        //TODO mongo now has an entity index, just needs CLI support.
        conf.setBoolean(ConfigUtils.USE_ENTITY, false);

        // FIXME RYA-215 We haven't enabled geo indexing in the console yet.
        //conf.set(OptionalConfigUtils.USE_GEO, "" + details.getGeoIndexDetails().isEnabled() );

        // Enable the supported indexers that the instance is configured to use.
        conf.setBoolean(ConfigUtils.USE_FREETEXT, ryaDetails.getFreeTextIndexDetails().isEnabled());
        conf.setBoolean(ConfigUtils.USE_TEMPORAL, ryaDetails.getTemporalIndexDetails().isEnabled());

        // This initializes the living indexers that will be used by the application and
        // caches them within the configuration object so that they may be used later.
        ConfigUtils.setIndexers(conf);

        return conf;
    }
}