/**
 * 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;
  }
}
