/**
 * 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.FilenameFilter;
import java.io.IOException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.server.common.Storage;
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
import org.apache.hadoop.hdfs.server.common.StorageInfo;

import com.google.common.base.Preconditions;
import org.apache.hadoop.io.IOUtils;

public abstract class NNUpgradeUtil {
  
  private static final Log LOG = LogFactory.getLog(NNUpgradeUtil.class);
  
  /**
   * Return true if this storage dir can roll back to the previous storage
   * state, false otherwise. The NN will refuse to run the rollback operation
   * unless at least one JM or fsimage storage directory can roll back.
   * 
   * @param storage the storage info for the current state
   * @param prevStorage the storage info for the previous (unupgraded) state
   * @param targetLayoutVersion the layout version we intend to roll back to
   * @return true if this JM can roll back, false otherwise.
   * @throws IOException in the event of error
   */
  static boolean canRollBack(StorageDirectory sd, StorageInfo storage,
      StorageInfo prevStorage, int targetLayoutVersion) throws IOException {
    File prevDir = sd.getPreviousDir();
    if (!prevDir.exists()) {  // use current directory then
      LOG.info("Storage directory " + sd.getRoot()
               + " does not contain previous fs state.");
      // read and verify consistency with other directories
      storage.readProperties(sd);
      return false;
    }

    // read and verify consistency of the prev dir
    prevStorage.readPreviousVersionProperties(sd);

    if (prevStorage.getLayoutVersion() != targetLayoutVersion) {
      throw new IOException(
        "Cannot rollback to storage version " +
        prevStorage.getLayoutVersion() +
        " using this version of the NameNode, which uses storage version " +
        targetLayoutVersion + ". " +
        "Please use the previous version of HDFS to perform the rollback.");
    }
    
    return true;
  }

  /**
   * Finalize the upgrade. The previous dir, if any, will be renamed and
   * removed. After this is completed, rollback is no longer allowed.
   * 
   * @param sd the storage directory to finalize
   * @throws IOException in the event of error
   */
  static void doFinalize(StorageDirectory sd) throws IOException {
    File prevDir = sd.getPreviousDir();
    if (!prevDir.exists()) { // already discarded
      LOG.info("Directory " + prevDir + " does not exist.");
      LOG.info("Finalize upgrade for " + sd.getRoot()+ " is not required.");
      return;
    }
    LOG.info("Finalizing upgrade of storage directory " + sd.getRoot());
    Preconditions.checkState(sd.getCurrentDir().exists(),
        "Current directory must exist.");
    final File tmpDir = sd.getFinalizedTmp();
    // rename previous to tmp and remove
    NNStorage.rename(prevDir, tmpDir);
    NNStorage.deleteDir(tmpDir);
    LOG.info("Finalize upgrade for " + sd.getRoot()+ " is complete.");
  }
  
  /**
   * Perform any steps that must succeed across all storage dirs/JournalManagers
   * involved in an upgrade before proceeding onto the actual upgrade stage. If
   * a call to any JM's or local storage dir's doPreUpgrade method fails, then
   * doUpgrade will not be called for any JM. The existing current dir is
   * renamed to previous.tmp, and then a new, empty current dir is created.
   *
   * @param conf configuration for creating {@link EditLogFileOutputStream}
   * @param sd the storage directory to perform the pre-upgrade procedure.
   * @throws IOException in the event of error
   */
  static void doPreUpgrade(Configuration conf, StorageDirectory sd)
      throws IOException {
    LOG.info("Starting upgrade of storage directory " + sd.getRoot());

    // rename current to tmp
    renameCurToTmp(sd);

    final File curDir = sd.getCurrentDir();
    final File tmpDir = sd.getPreviousTmp();
    List<String> fileNameList = IOUtils.listDirectory(tmpDir, new FilenameFilter() {
      @Override
      public boolean accept(File dir, String name) {
        return dir.equals(tmpDir)
            && name.startsWith(NNStorage.NameNodeFile.EDITS.getName());
      }
    });

    for (String s : fileNameList) {
      File prevFile = new File(tmpDir, s);
      Preconditions.checkState(prevFile.canRead(),
          "Edits log file " + s + " is not readable.");
      File newFile = new File(curDir, prevFile.getName());
      Preconditions.checkState(newFile.createNewFile(),
          "Cannot create new edits log file in " + curDir);
      EditLogFileInputStream in = new EditLogFileInputStream(prevFile);
      EditLogFileOutputStream out =
          new EditLogFileOutputStream(conf, newFile, 512*1024);
      FSEditLogOp logOp = in.nextValidOp();
      while (logOp != null) {
        out.write(logOp);
        logOp = in.nextOp();
      }
      out.setReadyToFlush();
      out.flushAndSync(true);
      out.close();
      in.close();
    }
  }

  /**
   * Rename the existing current dir to previous.tmp, and create a new empty
   * current dir.
   */
  public static void renameCurToTmp(StorageDirectory sd) throws IOException {
    File curDir = sd.getCurrentDir();
    File prevDir = sd.getPreviousDir();
    final File tmpDir = sd.getPreviousTmp();

    Preconditions.checkState(curDir.exists(),
        "Current directory must exist for preupgrade.");
    Preconditions.checkState(!prevDir.exists(),
        "Previous directory must not exist for preupgrade.");
    Preconditions.checkState(!tmpDir.exists(),
        "Previous.tmp directory must not exist for preupgrade."
            + "Consider restarting for recovery.");

    // rename current to tmp
    NNStorage.rename(curDir, tmpDir);

    if (!curDir.mkdir()) {
      throw new IOException("Cannot create directory " + curDir);
    }
  }
  
  /**
   * Perform the upgrade of the storage dir to the given storage info. The new
   * storage info is written into the current directory, and the previous.tmp
   * directory is renamed to previous.
   * 
   * @param sd the storage directory to upgrade
   * @param storage info about the new upgraded versions.
   * @throws IOException in the event of error
   */
  public static void doUpgrade(StorageDirectory sd, Storage storage)
      throws IOException {
    LOG.info("Performing upgrade of storage directory " + sd.getRoot());
    try {
      // Write the version file, since saveFsImage only makes the
      // fsimage_<txid>, and the directory is otherwise empty.
      storage.writeProperties(sd);

      File prevDir = sd.getPreviousDir();
      File tmpDir = sd.getPreviousTmp();
      Preconditions.checkState(!prevDir.exists(),
          "previous directory must not exist for upgrade.");
      Preconditions.checkState(tmpDir.exists(),
          "previous.tmp directory must exist for upgrade.");

      // rename tmp to previous
      NNStorage.rename(tmpDir, prevDir);
    } catch (IOException ioe) {
      LOG.error("Unable to rename temp to previous for " + sd.getRoot(), ioe);
      throw ioe;
    }
  }

  /**
   * Perform rollback of the storage dir to the previous state. The existing
   * current dir is removed, and the previous dir is renamed to current.
   * 
   * @param sd the storage directory to roll back.
   * @throws IOException in the event of error
   */
  static void doRollBack(StorageDirectory sd)
      throws IOException {
    File prevDir = sd.getPreviousDir();
    if (!prevDir.exists()) {
      return;
    }

    File tmpDir = sd.getRemovedTmp();
    Preconditions.checkState(!tmpDir.exists(),
        "removed.tmp directory must not exist for rollback."
            + "Consider restarting for recovery.");
    // rename current to tmp
    File curDir = sd.getCurrentDir();
    Preconditions.checkState(curDir.exists(),
        "Current directory must exist for rollback.");

    NNStorage.rename(curDir, tmpDir);
    // rename previous to current
    NNStorage.rename(prevDir, curDir);

    // delete tmp dir
    NNStorage.deleteDir(tmpDir);
    LOG.info("Rollback of " + sd.getRoot() + " is complete.");
  }
  
}
