/*
 * 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.accumulo.core.spi.fs;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.accumulo.core.data.TableId;
import org.apache.accumulo.core.spi.fs.VolumeChooserEnvironment.Scope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A {@link VolumeChooser} that delegates to another volume chooser based on other properties:
 * table.custom.volume.chooser for tables, and general.custom.volume.chooser.scoped for scopes.
 * general.custom.volume.chooser.{scope} can override the system wide setting for
 * general.custom.volume.chooser.scoped. At the this this was written, the only known scope was
 * "logger".
 *
 * @since 2.1.0
 */
public class PerTableVolumeChooser implements VolumeChooser {
  // TODO rename this class to DelegatingChooser? It delegates for more than just per-table scope
  private static final Logger log = LoggerFactory.getLogger(PerTableVolumeChooser.class);
  // TODO Add hint of expected size to construction, see ACCUMULO-3410
  /* Track VolumeChooser instances so they can keep state. */
  private final ConcurrentHashMap<TableId,VolumeChooser> tableSpecificChooserCache =
      new ConcurrentHashMap<>();
  private final ConcurrentHashMap<Scope,VolumeChooser> scopeSpecificChooserCache =
      new ConcurrentHashMap<>();

  private static final String TABLE_CUSTOM_SUFFIX = "volume.chooser";

  private static final String getCustomPropertySuffix(Scope scope) {
    return "volume.chooser." + scope.name().toLowerCase();
  }

  private static final String DEFAULT_SCOPED_VOLUME_CHOOSER =
      getCustomPropertySuffix(Scope.DEFAULT);

  @Override
  public String choose(VolumeChooserEnvironment env, Set<String> options) {
    log.trace("{}.choose", getClass().getSimpleName());
    return getDelegateChooser(env).choose(env, options);
  }

  @Override
  public Set<String> choosable(VolumeChooserEnvironment env, Set<String> options) {
    return getDelegateChooser(env).choosable(env, options);
  }

  // visible (not private) for testing
  VolumeChooser getDelegateChooser(VolumeChooserEnvironment env) {
    if (env.getChooserScope() == Scope.TABLE) {
      return getVolumeChooserForTable(env);
    }
    return getVolumeChooserForScope(env);
  }

  private VolumeChooser getVolumeChooserForTable(VolumeChooserEnvironment env) {
    log.trace("Looking up property {} for table id: {}", TABLE_CUSTOM_SUFFIX, env.getTable());

    String clazz = env.getServiceEnv().getConfiguration(env.getTable().get())
        .getTableCustom(TABLE_CUSTOM_SUFFIX);

    // fall back to global default scope, so setting only one default is necessary, rather than a
    // separate default for TABLE scope than other scopes
    if (clazz == null || clazz.isEmpty()) {
      clazz = env.getServiceEnv().getConfiguration().getCustom(DEFAULT_SCOPED_VOLUME_CHOOSER);
    }

    if (clazz == null || clazz.isEmpty()) {
      String msg = "Property " + TABLE_CUSTOM_SUFFIX + " or " + DEFAULT_SCOPED_VOLUME_CHOOSER
          + " must be a valid " + VolumeChooser.class.getSimpleName() + " to use the "
          + getClass().getSimpleName();
      throw new RuntimeException(msg);
    }

    return createVolumeChooser(env, clazz, TABLE_CUSTOM_SUFFIX, env.getTable().get(),
        tableSpecificChooserCache);
  }

  private VolumeChooser getVolumeChooserForScope(VolumeChooserEnvironment env) {
    Scope scope = env.getChooserScope();
    String property = getCustomPropertySuffix(scope);
    log.trace("Looking up property {} for scope: {}", property, scope);

    String clazz = env.getServiceEnv().getConfiguration().getCustom(property);

    // fall back to global default scope if this scope isn't configured (and not already default
    // scope)
    if ((clazz == null || clazz.isEmpty()) && scope != Scope.DEFAULT) {
      log.debug("{} not found; using {}", property, DEFAULT_SCOPED_VOLUME_CHOOSER);
      clazz = env.getServiceEnv().getConfiguration().getCustom(DEFAULT_SCOPED_VOLUME_CHOOSER);

      if (clazz == null || clazz.isEmpty()) {
        String msg =
            "Property " + property + " or " + DEFAULT_SCOPED_VOLUME_CHOOSER + " must be a valid "
                + VolumeChooser.class.getSimpleName() + " to use the " + getClass().getSimpleName();
        throw new RuntimeException(msg);
      }

      property = DEFAULT_SCOPED_VOLUME_CHOOSER;
    }

    return createVolumeChooser(env, clazz, property, scope, scopeSpecificChooserCache);
  }

  /**
   * Create a volume chooser, using the cached version if any. This will replace the cached version
   * if the class name has changed.
   *
   * @param clazz
   *          The volume chooser class name
   * @param property
   *          The property from which it was obtained
   * @param key
   *          The key to user in the cache
   * @param cache
   *          The cache
   * @return The volume chooser instance
   */
  private <T> VolumeChooser createVolumeChooser(VolumeChooserEnvironment env, String clazz,
      String property, T key, ConcurrentHashMap<T,VolumeChooser> cache) {
    final String className = clazz.trim();
    // create a new instance, unless another thread beat us with one of the same class name, then
    // use theirs
    return cache.compute(key, (k, previousChooser) -> {
      if (previousChooser != null && previousChooser.getClass().getName().equals(className)) {
        // no change; return the old one
        return previousChooser;
      } else if (previousChooser == null) {
        // TODO stricter definition of when the updated property is used, ref ACCUMULO-3412
        // don't log change if this is the first use
        log.trace("Change detected for {} for {}", property, key);
      }
      try {
        if (key instanceof TableId) {
          TableId tableId = (TableId) key;
          return env.getServiceEnv().instantiate(tableId, className, VolumeChooser.class);
        } else {
          return env.getServiceEnv().instantiate(className, VolumeChooser.class);
        }
      } catch (Exception e) {
        String msg = "Failed to create instance for " + key + " configured to use " + className
            + " via " + property;
        throw new RuntimeException(msg, e);
      }
    });
  }
}
