/*
 * 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.samza.config;

import org.apache.samza.SamzaException;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

/**
 * Elasticsearch configuration class to read elasticsearch specific configuration from Samza.
 */
public class ElasticsearchConfig extends MapConfig {

  private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchConfig.class);

  public static final String CONFIG_KEY_CLIENT_FACTORY = "client.factory";
  public static final String PREFIX_ELASTICSEARCH_SETTINGS = "client.elasticsearch.";

  public static final String CONFIG_KEY_INDEX_REQUEST_FACTORY = "index.request.factory";

  public static final String CONFIG_KEY_BULK_FLUSH_MAX_ACTIONS = "bulk.flush.max.actions";
  public static final String CONFIG_KEY_BULK_FLUSH_MAX_SIZE_MB = "bulk.flush.max.size.mb";
  public static final String CONFIG_KEY_BULK_FLUSH_INTERVALS_MS = "bulk.flush.interval.ms";

  public static final String CONFIG_KEY_CLIENT_TRANSPORT_HOST = "client.transport.host";
  public static final String CONFIG_KEY_CLIENT_TRANSPORT_PORT = "client.transport.port";

  public ElasticsearchConfig(String name, Config config) {
    super(config.subset("systems." + name + "."));

    logAllSettings(this);
  }

  // Client settings
  public String getClientFactoryClassName() {
    if (containsKey(CONFIG_KEY_CLIENT_FACTORY)) {
      return get(CONFIG_KEY_CLIENT_FACTORY);
    } else {
      throw new SamzaException("You must specify a client factory class"
                               + " for the Elasticsearch system.");
    }
  }

  public Config getElasticseachSettings() {
    return subset(PREFIX_ELASTICSEARCH_SETTINGS);
  }

  // Index Request
  public Optional<String> getIndexRequestFactoryClassName() {
      return Optional.ofNullable(get(CONFIG_KEY_INDEX_REQUEST_FACTORY));
  }

  // Transport client settings
  public Optional<String> getTransportHost() {
      return Optional.ofNullable(get(CONFIG_KEY_CLIENT_TRANSPORT_HOST));
  }

  public Optional<Integer> getTransportPort() {
    if (containsKey(CONFIG_KEY_CLIENT_TRANSPORT_PORT)) {
      return Optional.of(getInt(CONFIG_KEY_CLIENT_TRANSPORT_PORT));
    } else {
      return Optional.empty();
    }
  }

  // Bulk processor settings
  public Optional<Integer> getBulkFlushMaxActions() {
    if (containsKey(CONFIG_KEY_BULK_FLUSH_MAX_ACTIONS)) {
      return Optional.of(getInt(CONFIG_KEY_BULK_FLUSH_MAX_ACTIONS));
    } else {
      return Optional.empty();
    }
  }

  public Optional<Integer> getBulkFlushMaxSizeMB() {
    if (containsKey(CONFIG_KEY_BULK_FLUSH_MAX_SIZE_MB)) {
      return Optional.of(getInt(CONFIG_KEY_BULK_FLUSH_MAX_SIZE_MB));
    } else {
      return Optional.empty();
    }
  }

  public Optional<Integer> getBulkFlushIntervalMS() {
    if (containsKey(CONFIG_KEY_BULK_FLUSH_INTERVALS_MS)) {
      return Optional.of(getInt(CONFIG_KEY_BULK_FLUSH_INTERVALS_MS));
    } else {
      return Optional.empty();
    }
  }

  private void logAllSettings(Config config) {
    StringBuilder b = new StringBuilder();
    b.append("Elasticsearch System settings: ");
    b.append("\n");
    for (Map.Entry<String, String> entry : config.entrySet()) {
      b.append('\t');
      b.append(entry.getKey());
      b.append(" = ");
      b.append(entry.getValue());
      b.append("\n");
    }
    LOGGER.info(b.toString());
  }
}
