/*
 * 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.indexing.external.fluo;

import static com.google.common.base.Preconditions.checkNotNull;

import org.apache.hadoop.conf.Configuration;
import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
import org.apache.rya.indexing.accumulo.ConfigUtils;

import com.google.common.base.Optional;

/**
 * Configuration values required to initialize a {@link FluoPcjUpdater}.
 */
public final class FluoPcjUpdaterConfig {

    // Defines which Fluo application is running for this instance of Rya.
    public static final String FLUO_APP_NAME = ConfigUtils.FLUO_APP_NAME;

    // Values that define which Accumulo instance hosts the Fluo application's table.
    public static final String ACCUMULO_ZOOKEEPERS = ConfigUtils.CLOUDBASE_ZOOKEEPERS;
    public static final String ACCUMULO_INSTANCE = ConfigUtils.CLOUDBASE_INSTANCE;
    public static final String ACCUMULO_USERNAME = ConfigUtils.CLOUDBASE_USER;
    public static final String ACCUMULO_PASSWORD = ConfigUtils.CLOUDBASE_PASSWORD;

    // Values that define the visibilities associated with statement that are inserted by the fluo updater.
    public static final String STATEMENT_VISIBILITY = RdfCloudTripleStoreConfiguration.CONF_QUERY_AUTH;

    // The configuration object that is provided to Secondary Indexing implementations.
    private final Configuration config;

    /**
     * Constructs an instance of {@link FluoPcjUpdaterConfig}.
     *
     * @param config - The configuration values that will be interpreted. (not null)
     */
    public FluoPcjUpdaterConfig(final Configuration config) {
        this.config = checkNotNull(config);
    }

    /**
     * @return The name of the Fluo Application this instance of RYA is
     *   using to incrementally update PCJs.
     */
    public Optional<String> getFluoAppName() {
        return Optional.fromNullable(config.get(FLUO_APP_NAME));
    }

    /**
     * This value is the {@link #getAccumuloInstance()} value appended with the
     * "/fluo" namespace.
     *
     * @return The zookeepers that are used to manage Fluo state. ({@code null}
     *   if not configured)
     */
    public Optional<String> getFluoZookeepers() {
        final Optional<String> accumuloZookeepers = getAccumuloZookeepers();
        if(!accumuloZookeepers.isPresent()) {
            return Optional.absent();
        }
        return Optional.of( accumuloZookeepers.get() + "/fluo" );
    }

    /**
     * @return The zookeepers used to connect to the Accumulo instance that
     *   is storing the state of the Fluo Application.
     */
    public Optional<String> getAccumuloZookeepers() {
        return Optional.fromNullable(config.get(ACCUMULO_ZOOKEEPERS));
    }

    /**
     * @return The instance name of the Accumulo instance that is storing
     *   the state of the Fluo Application.
     */
    public Optional<String> getAccumuloInstance() {
        return Optional.fromNullable(config.get(ACCUMULO_INSTANCE));
    }

    /**
     * @return The username the indexer will authenticate when connecting
     *   to the Accumulo instance that stores the state of the Fluo Application.
     */
    public Optional<String> getAccumuloUsername() {
        return Optional.fromNullable(config.get(ACCUMULO_USERNAME));
    }

    /**
     * @return The password the indexer will authenticate when connecting
     *   to the Accumulo instance that stores the state of the Fluo Application.
     */
    public Optional<String> getAccumuloPassword() {
        return Optional.fromNullable(config.get(ACCUMULO_PASSWORD));
    }

    /**
     * @return The visibility labels that will be attached to the statements
     *   that are inserted into the Fluo Application.
     */
    public Optional<String> getStatementVisibility() {
        return Optional.fromNullable(config.get(STATEMENT_VISIBILITY));
    }
}