/**
 * 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.contrib.index.main;

import java.io.IOException;
import java.text.NumberFormat;
import java.util.Arrays;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.contrib.index.mapred.IndexUpdateConfiguration;
import org.apache.hadoop.contrib.index.mapred.IIndexUpdater;
import org.apache.hadoop.contrib.index.mapred.Shard;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.util.ReflectionUtils;

/**
 * A distributed "index" is partitioned into "shards". Each shard corresponds
 * to a Lucene instance. This class contains the main() method which uses a
 * Map/Reduce job to analyze documents and update Lucene instances in parallel.
 * 
 * The main() method in UpdateIndex requires the following information for
 * updating the shards:
 *   - Input formatter. This specifies how to format the input documents.
 *   - Analysis. This defines the analyzer to use on the input. The analyzer
 *     determines whether a document is being inserted, updated, or deleted.
 *     For inserts or updates, the analyzer also converts each input document
 *     into a Lucene document.
 *   - Input paths. This provides the location(s) of updated documents,
 *     e.g., HDFS files or directories, or HBase tables.
 *   - Shard paths, or index path with the number of shards. Either specify
 *     the path for each shard, or specify an index path and the shards are
 *     the sub-directories of the index directory.
 *   - Output path. When the update to a shard is done, a message is put here.
 *   - Number of map tasks.
 *
 * All of the information can be specified in a configuration file. All but
 * the first two can also be specified as command line options. Check out
 * conf/index-config.xml.template for other configurable parameters.
 *
 * Note: Because of the parallel nature of Map/Reduce, the behaviour of
 * multiple inserts, deletes or updates to the same document is undefined.
 */
public class UpdateIndex {
  public static final Log LOG = LogFactory.getLog(UpdateIndex.class);

  private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
  static {
    NUMBER_FORMAT.setMinimumIntegerDigits(5);
    NUMBER_FORMAT.setGroupingUsed(false);
  }

  private static long now() {
    return System.currentTimeMillis();
  }

  private static void printUsage(String cmd) {
    System.err.println("Usage: java " + UpdateIndex.class.getName() + "\n"
        + "                        -inputPaths <inputPath,inputPath>\n"
        + "                        -outputPath <outputPath>\n"
        + "                        -shards     <shardDir,shardDir>\n"
        + "                        -indexPath  <indexPath>\n"
        + "                        -numShards  <num>\n"
        + "                        -numMapTasks <num>\n"
        + "                        -conf       <confPath>\n"
        + "Note: Do not use both -shards option and -indexPath option.");
  }

  private static String getIndexPath(Configuration conf) {
    return conf.get("sea.index.path");
  }

  private static int getNumShards(Configuration conf) {
    return conf.getInt("sea.num.shards", 1);
  }

  private static Shard[] createShards(String indexPath, int numShards,
      Configuration conf) throws IOException {

    String parent = Shard.normalizePath(indexPath) + Path.SEPARATOR;
    long versionNumber = -1;
    long generation = -1;

    FileSystem fs = FileSystem.get(conf);
    Path path = new Path(indexPath);

    if (fs.exists(path)) {
      FileStatus[] fileStatus = fs.listStatus(path);
      String[] shardNames = new String[fileStatus.length];
      int count = 0;
      for (int i = 0; i < fileStatus.length; i++) {
        if (fileStatus[i].isDirectory()) {
          shardNames[count] = fileStatus[i].getPath().getName();
          count++;
        }
      }
      Arrays.sort(shardNames, 0, count);

      Shard[] shards = new Shard[count >= numShards ? count : numShards];
      for (int i = 0; i < count; i++) {
        shards[i] =
            new Shard(versionNumber, parent + shardNames[i], generation);
      }

      int number = count;
      for (int i = count; i < numShards; i++) {
        String shardPath;
        while (true) {
          shardPath = parent + NUMBER_FORMAT.format(number++);
          if (!fs.exists(new Path(shardPath))) {
            break;
          }
        }
        shards[i] = new Shard(versionNumber, shardPath, generation);
      }
      return shards;
    } else {
      Shard[] shards = new Shard[numShards];
      for (int i = 0; i < shards.length; i++) {
        shards[i] =
            new Shard(versionNumber, parent + NUMBER_FORMAT.format(i),
                generation);
      }
      return shards;
    }
  }

  /**
   * The main() method
   * @param argv
   */
  public static void main(String[] argv) {
    if (argv.length == 0) {
      printUsage("");
      System.exit(-1);
    }

    String inputPathsString = null;
    Path outputPath = null;
    String shardsString = null;
    String indexPath = null;
    int numShards = -1;
    int numMapTasks = -1;
    Configuration conf = new Configuration();
    String confPath = null;

    // parse the command line
    for (int i = 0; i < argv.length; i++) { // parse command line
      if (argv[i].equals("-inputPaths")) {
        inputPathsString = argv[++i];
      } else if (argv[i].equals("-outputPath")) {
        outputPath = new Path(argv[++i]);
      } else if (argv[i].equals("-shards")) {
        shardsString = argv[++i];
      } else if (argv[i].equals("-indexPath")) {
        indexPath = argv[++i];
      } else if (argv[i].equals("-numShards")) {
        numShards = Integer.parseInt(argv[++i]);
      } else if (argv[i].equals("-numMapTasks")) {
        numMapTasks = Integer.parseInt(argv[++i]);
      } else if (argv[i].equals("-conf")) {
        // add as a local FS resource
        confPath = argv[++i];
        conf.addResource(new Path(confPath));
      } else {
        System.out.println("Unknown option " + argv[i] + " w/ value "
            + argv[++i]);
      }
    }
    LOG.info("inputPaths = " + inputPathsString);
    LOG.info("outputPath = " + outputPath);
    LOG.info("shards     = " + shardsString);
    LOG.info("indexPath  = " + indexPath);
    LOG.info("numShards  = " + numShards);
    LOG.info("numMapTasks= " + numMapTasks);
    LOG.info("confPath   = " + confPath);

    Path[] inputPaths = null;
    Shard[] shards = null;

    JobConf jobConf = new JobConf(conf);
    IndexUpdateConfiguration iconf = new IndexUpdateConfiguration(jobConf);

    if (inputPathsString != null) {
      jobConf.set(org.apache.hadoop.mapreduce.lib.input.
        FileInputFormat.INPUT_DIR, inputPathsString);
    }
    inputPaths = FileInputFormat.getInputPaths(jobConf);
    if (inputPaths.length == 0) {
      inputPaths = null;
    }

    if (outputPath == null) {
      outputPath = FileOutputFormat.getOutputPath(jobConf);
    }

    if (inputPaths == null || outputPath == null) {
      System.err.println("InputPaths and outputPath must be specified.");
      printUsage("");
      System.exit(-1);
    }

    if (shardsString != null) {
      iconf.setIndexShards(shardsString);
    }
    shards = Shard.getIndexShards(iconf);
    if (shards != null && shards.length == 0) {
      shards = null;
    }

    if (indexPath == null) {
      indexPath = getIndexPath(conf);
    }
    if (numShards <= 0) {
      numShards = getNumShards(conf);
    }

    if (shards == null && indexPath == null) {
      System.err.println("Either shards or indexPath must be specified.");
      printUsage("");
      System.exit(-1);
    }

    if (numMapTasks <= 0) {
      numMapTasks = jobConf.getNumMapTasks();
    }

    try {
      // create shards and set their directories if necessary
      if (shards == null) {
        shards = createShards(indexPath, numShards, conf);
      }

      long startTime = now();
      try {
        IIndexUpdater updater =
            (IIndexUpdater) ReflectionUtils.newInstance(
                iconf.getIndexUpdaterClass(), conf);
        LOG.info("sea.index.updater = "
            + iconf.getIndexUpdaterClass().getName());

        updater.run(conf, inputPaths, outputPath, numMapTasks, shards);
        LOG.info("Index update job is done");

      } finally {
        long elapsedTime = now() - startTime;
        LOG.info("Elapsed time is  " + (elapsedTime / 1000) + "s");
        System.out.println("Elapsed time is " + (elapsedTime / 1000) + "s");
      }
    } catch (Exception e) {
      e.printStackTrace(System.err);
    }
  }
}
