/**
 * 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 org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.hdfs.protocol.Block;
import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo;
import org.apache.hadoop.hdfs.server.common.GenerationStamp;
import org.apache.hadoop.hdfs.server.common.Storage;

/**
 * 
 * CreateEditsLog
 *   Synopsis: CreateEditsLog -f numFiles StartingBlockId numBlocksPerFile
 *        [-r replicafactor] [-d editsLogDirectory]
 *             Default replication factor is 1
 *             Default edits log directory is /tmp/EditsLogOut
 *   
 *   Create a name node's edits log in /tmp/EditsLogOut.
 *   The file /tmp/EditsLogOut/current/edits can be copied to a name node's
 *   dfs.namenode.name.dir/current direcotry and the name node can be started as usual.
 *   
 *   The files are created in /createdViaInjectingInEditsLog
 *   The file names contain the starting and ending blockIds; hence once can 
 *   create multiple edits logs using this command using non overlapping 
 *   block ids and feed the files to a single name node.
 *   
 *   See Also @link #DataNodeCluster for injecting a set of matching
 *   blocks created with this command into a set of simulated data nodes.
 *
 */

public class CreateEditsLog {
  static final String BASE_PATH = "/createdViaInjectingInEditsLog";
  static final String EDITS_DIR = "/tmp/EditsLogOut";
  static String edits_dir = EDITS_DIR;
  static final public long BLOCK_GENERATION_STAMP =
      GenerationStamp.LAST_RESERVED_STAMP;
  
  static void addFiles(FSEditLog editLog, int numFiles, short replication, 
                         int blocksPerFile, long startingBlockId, long blockSize,
                         FileNameGenerator nameGenerator) {
    
    PermissionStatus p = new PermissionStatus("joeDoe", "people",
                                      new FsPermission((short)0777));
    INodeId inodeId = new INodeId();
    INodeDirectory dirInode = new INodeDirectory(inodeId.nextValue(), null, p,
      0L);
    editLog.logMkDir(BASE_PATH, dirInode);
    BlockInfo[] blocks = new BlockInfo[blocksPerFile];
    for (int iB = 0; iB < blocksPerFile; ++iB) {
      blocks[iB] = 
       new BlockInfo(new Block(0, blockSize, BLOCK_GENERATION_STAMP),
                               replication);
    }
    
    long currentBlockId = startingBlockId;
    long bidAtSync = startingBlockId;

    for (int iF = 0; iF < numFiles; iF++) {
      for (int iB = 0; iB < blocksPerFile; ++iB) {
         blocks[iB].setBlockId(currentBlockId++);
      }

      final INodeFile inode = new INodeFile(inodeId.nextValue(), null,
          p, 0L, 0L, blocks, replication, blockSize);
      inode.toUnderConstruction("", "");

     // Append path to filename with information about blockIDs 
      String path = "_" + iF + "_B" + blocks[0].getBlockId() + 
                    "_to_B" + blocks[blocksPerFile-1].getBlockId() + "_";
      String filePath = nameGenerator.getNextFileName("");
      filePath = filePath + path;
      // Log the new sub directory in edits
      if ((iF % nameGenerator.getFilesPerDirectory())  == 0) {
        String currentDir = nameGenerator.getCurrentDir();
        dirInode = new INodeDirectory(inodeId.nextValue(), null, p, 0L);
        editLog.logMkDir(currentDir, dirInode);
      }
      INodeFile fileUc = new INodeFile(inodeId.nextValue(), null,
          p, 0L, 0L, BlockInfo.EMPTY_ARRAY, replication, blockSize);
      fileUc.toUnderConstruction("", "");
      editLog.logOpenFile(filePath, fileUc, false);
      editLog.logCloseFile(filePath, inode);

      if (currentBlockId - bidAtSync >= 2000) { // sync every 2K blocks
        editLog.logSync();
        bidAtSync = currentBlockId;
      }
    }
    System.out.println("Created edits log in directory " + edits_dir);
    System.out.println(" containing " +
       numFiles + " File-Creates, each file with " + blocksPerFile + " blocks");
    System.out.println(" blocks range: " + 
        startingBlockId + " to " + (currentBlockId-1));
  }
  
  static final String usage = "Usage: createditlogs " +
  " -f  numFiles startingBlockIds NumBlocksPerFile  [-r replicafactor] " + 
  		"[-d editsLogDirectory]\n" + 
  		"      Default replication factor is 1\n" +
  		"      Default edits log direcory is " + EDITS_DIR + "\n";



  static void printUsageExit() {
    System.out.println(usage);
    System.exit(-1); 
    }
    static void printUsageExit(String err) {
    System.out.println(err);
    printUsageExit();
  }
  /**
   * @param args arguments
   * @throws IOException 
   */
  public static void main(String[] args)  throws IOException {
    long startingBlockId = 1;
    int numFiles = 0;
    short replication = 1;
    int numBlocksPerFile = 0;
    long blockSize = 10;

    if (args.length == 0) {
      printUsageExit();
    }

    for (int i = 0; i < args.length; i++) { // parse command line
      if (args[i].equals("-h"))
        printUsageExit();
      if (args[i].equals("-f")) {
       if (i + 3 >= args.length || args[i+1].startsWith("-") || 
           args[i+2].startsWith("-") || args[i+3].startsWith("-")) {
         printUsageExit(
             "Missing num files, starting block and/or number of blocks");
       }
       numFiles = Integer.parseInt(args[++i]);
       startingBlockId = Integer.parseInt(args[++i]);
       numBlocksPerFile = Integer.parseInt(args[++i]);
       if (numFiles <=0 || numBlocksPerFile <= 0) {
         printUsageExit("numFiles and numBlocksPerFile most be greater than 0");
       }
      } else if (args[i].equals("-l")) {
        if (i + 1 >= args.length) {
          printUsageExit(
              "Missing block length");
        }
        blockSize = Long.parseLong(args[++i]);
      } else if (args[i].equals("-r") || args[i+1].startsWith("-")) {
        if (i + 1 >= args.length) {
          printUsageExit(
              "Missing replication factor");
        }
        replication = Short.parseShort(args[++i]);
      } else if (args[i].equals("-d")) {
        if (i + 1 >= args.length || args[i+1].startsWith("-")) {
          printUsageExit("Missing edits logs directory");
        }
        edits_dir = args[++i];
      } else {
        printUsageExit();
      }
    }
    

    File editsLogDir = new File(edits_dir);
    File subStructureDir = new File(edits_dir + "/" + 
        Storage.STORAGE_DIR_CURRENT);
    if ( !editsLogDir.exists() ) {
      if ( !editsLogDir.mkdir()) {
        System.out.println("cannot create " + edits_dir);
        System.exit(-1);
      }
    }
    if ( !subStructureDir.exists() ) {
      if ( !subStructureDir.mkdir()) {
        System.out.println("cannot create subdirs of " + edits_dir);
        System.exit(-1);
      }
    }
    

    FileNameGenerator nameGenerator = new FileNameGenerator(BASE_PATH, 100);
    FSEditLog editLog = FSImageTestUtil.createStandaloneEditLog(editsLogDir);
    editLog.openForWrite();
    addFiles(editLog, numFiles, replication, numBlocksPerFile, startingBlockId,
             blockSize, nameGenerator);
    editLog.logSync();
    editLog.close();
  }
}
