/**
 * 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.hadoop.hdfs.server.namenode;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.DF;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.server.common.Util;

import com.google.common.annotations.VisibleForTesting;

/**
 * 
 * NameNodeResourceChecker provides a method -
 * <code>hasAvailableDiskSpace</code> - which will return true if and only if
 * the NameNode has disk space available on all volumes which are configured to
 * be checked. Volumes containing file system name/edits dirs are added by
 * default, and arbitrary extra volumes may be configured as well.
 */
public class NameNodeResourceChecker {
  private static final Log LOG = LogFactory.getLog(NameNodeResourceChecker.class.getName());

  // Space (in bytes) reserved per volume.
  private long duReserved;

  private final Configuration conf;
  private Map<String, DF> volumes;

  /**
   * Create a NameNodeResourceChecker, which will check the name dirs and edits
   * dirs set in <code>conf</code>.
   * 
   * @param conf
   * @throws IOException
   */
  public NameNodeResourceChecker(Configuration conf) throws IOException {
    this.conf = conf;
    volumes = new HashMap<String, DF>();

    duReserved = conf.getLong(DFSConfigKeys.DFS_NAMENODE_DU_RESERVED_KEY,
        DFSConfigKeys.DFS_NAMENODE_DU_RESERVED_DEFAULT);

    Collection<URI> extraCheckedVolumes = Util.stringCollectionAsURIs(conf
        .getTrimmedStringCollection(DFSConfigKeys.DFS_NAMENODE_CHECKED_VOLUMES_KEY));

    addDirsToCheck(FSNamesystem.getNamespaceDirs(conf));
    addDirsToCheck(FSNamesystem.getNamespaceEditsDirs(conf));
    addDirsToCheck(extraCheckedVolumes);
  }

  /**
   * Add the passed-in directories to the list of volumes to check.
   * 
   * @param directoriesToCheck
   *          The directories whose volumes will be checked for available space.
   * @throws IOException
   */
  private void addDirsToCheck(Collection<URI> directoriesToCheck)
      throws IOException {
    for (URI directoryUri : directoriesToCheck) {
      File dir = new File(directoryUri.getPath());
      if (!dir.exists()) {
        throw new IOException("Missing directory "+dir.getAbsolutePath());
      }
      DF df = new DF(dir, conf);
      volumes.put(df.getFilesystem(), df);
    }
  }

  /**
   * Return true if disk space is available on at least one of the configured
   * volumes.
   * 
   * @return True if the configured amount of disk space is available on at
   *         least one volume, false otherwise.
   * @throws IOException
   */
  boolean hasAvailableDiskSpace()
      throws IOException {
    return getVolumesLowOnSpace().size() < volumes.size();
  }

  /**
   * Return the set of directories which are low on space.
   * @return the set of directories whose free space is below the threshold.
   * @throws IOException 
   */
  Collection<String> getVolumesLowOnSpace() throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Going to check the following volumes disk space: " + volumes);
    }
    Collection<String> lowVolumes = new ArrayList<String>();
    for (DF volume : volumes.values()) {
      long availableSpace = volume.getAvailable();
      String fileSystem = volume.getFilesystem();
      if (LOG.isDebugEnabled()) {
        LOG.debug("Space available on volume '" + fileSystem + "' is " + availableSpace);
      }
      if (availableSpace < duReserved) {
        LOG.warn("Space available on volume '" + fileSystem + "' is "
            + availableSpace +
            ", which is below the configured reserved amount " + duReserved);
        lowVolumes.add(volume.getFilesystem());
      }
    }
    return lowVolumes;
  }
  
  @VisibleForTesting
  void setVolumes(Map<String, DF> volumes) {
    this.volumes = volumes;
  }
}
