/*
 * 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.accumulo.shell.commands;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

import org.apache.accumulo.core.classloader.ClassLoaderUtil;
import org.apache.accumulo.core.client.AccumuloException;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.IteratorSetting;
import org.apache.accumulo.core.client.SampleNotPresentException;
import org.apache.accumulo.core.client.Scanner;
import org.apache.accumulo.core.client.ScannerBase;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.apache.accumulo.core.client.sample.SamplerConfiguration;
import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
import org.apache.accumulo.core.data.Value;
import org.apache.accumulo.core.iterators.SortedKeyValueIterator;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.util.format.Formatter;
import org.apache.accumulo.core.util.format.FormatterConfig;
import org.apache.accumulo.core.util.interpret.DefaultScanInterpreter;
import org.apache.accumulo.core.util.interpret.ScanInterpreter;
import org.apache.accumulo.shell.Shell;
import org.apache.accumulo.shell.Shell.Command;
import org.apache.accumulo.shell.Shell.PrintFile;
import org.apache.accumulo.shell.ShellCommandException;
import org.apache.accumulo.shell.ShellCommandException.ErrorCode;
import org.apache.accumulo.shell.ShellUtil;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.hadoop.io.Text;

public class ScanCommand extends Command {

  private Option scanOptAuths, scanOptRow, scanOptColumns, disablePaginationOpt, showFewOpt,
      formatterOpt, interpreterOpt, formatterInterpeterOpt, outputFileOpt;

  protected Option timestampOpt;
  protected Option profileOpt;
  private Option optStartRowExclusive;
  private Option optStartRowInclusive;
  private Option optEndRowExclusive;
  private Option timeoutOption;
  private Option sampleOpt;
  private Option contextOpt;
  private Option executionHintsOpt;

  protected void setupSampling(final String tableName, final CommandLine cl, final Shell shellState,
      ScannerBase scanner)
      throws TableNotFoundException, AccumuloException, AccumuloSecurityException {
    if (getUseSample(cl)) {
      SamplerConfiguration samplerConfig =
          shellState.getAccumuloClient().tableOperations().getSamplerConfiguration(tableName);
      if (samplerConfig == null) {
        throw new SampleNotPresentException(
            "Table " + tableName + " does not have sampling configured");
      }
      Shell.log.debug("Using sampling configuration : {}", samplerConfig);
      scanner.setSamplerConfiguration(samplerConfig);
    }
  }

  @Override
  public int execute(final String fullCommand, final CommandLine cl, final Shell shellState)
      throws Exception {
    try (final PrintFile printFile = getOutputFile(cl)) {
      final String tableName = OptUtil.getTableOpt(cl, shellState);

      final Class<? extends Formatter> formatter = getFormatter(cl, tableName, shellState);
      final ScanInterpreter interpeter = getInterpreter(cl, tableName, shellState);

      String classLoaderContext = null;
      if (cl.hasOption(contextOpt.getOpt())) {
        classLoaderContext = cl.getOptionValue(contextOpt.getOpt());
      }
      // handle first argument, if present, the authorizations list to
      // scan with
      final Authorizations auths = getAuths(cl, shellState);
      final Scanner scanner = shellState.getAccumuloClient().createScanner(tableName, auths);
      if (classLoaderContext != null) {
        scanner.setClassLoaderContext(classLoaderContext);
      }
      // handle session-specific scan iterators
      addScanIterators(shellState, cl, scanner, tableName);

      // handle remaining optional arguments
      scanner.setRange(getRange(cl, interpeter));

      // handle columns
      fetchColumns(cl, scanner, interpeter);

      // set timeout
      scanner.setTimeout(getTimeout(cl), TimeUnit.MILLISECONDS);

      setupSampling(tableName, cl, shellState, scanner);

      scanner.setExecutionHints(ShellUtil.parseMapOpt(cl, executionHintsOpt));

      // output the records

      final FormatterConfig config = new FormatterConfig();
      config.setPrintTimestamps(cl.hasOption(timestampOpt.getOpt()));
      if (cl.hasOption(showFewOpt.getOpt())) {
        final String showLength = cl.getOptionValue(showFewOpt.getOpt());
        try {
          final int length = Integer.parseInt(showLength);
          config.setShownLength(length);
        } catch (NumberFormatException nfe) {
          Shell.log.error("Arg must be an integer.", nfe);
        } catch (IllegalArgumentException iae) {
          Shell.log.error("Arg must be greater than one.", iae);
        }
      }
      printRecords(cl, shellState, config, scanner, formatter, printFile);
    }

    return 0;
  }

  protected boolean getUseSample(CommandLine cl) {
    return cl.hasOption(sampleOpt.getLongOpt());
  }

  protected long getTimeout(final CommandLine cl) {
    if (cl.hasOption(timeoutOption.getLongOpt())) {
      return ConfigurationTypeHelper.getTimeInMillis(cl.getOptionValue(timeoutOption.getLongOpt()));
    }

    return Long.MAX_VALUE;
  }

  static void ensureTserversCanLoadIterator(final Shell shellState, String tableName,
      String classname) throws AccumuloException, AccumuloSecurityException, TableNotFoundException,
      ShellCommandException {
    if (!shellState.getAccumuloClient().tableOperations().testClassLoad(tableName, classname,
        SortedKeyValueIterator.class.getName())) {
      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE,
          "Servers are unable to load " + classname + " as type "
              + SortedKeyValueIterator.class.getName());
    }
  }

  protected void addScanIterators(final Shell shellState, CommandLine cl, final ScannerBase scanner,
      final String tableName) throws Exception {

    List<IteratorSetting> tableScanIterators;
    if (cl.hasOption(profileOpt.getOpt())) {
      String profile = cl.getOptionValue(profileOpt.getOpt());
      tableScanIterators = shellState.iteratorProfiles.get(profile);

      if (tableScanIterators == null) {
        throw new IllegalArgumentException("Profile " + profile + " does not exist");
      }

      for (IteratorSetting iteratorSetting : tableScanIterators) {
        ensureTserversCanLoadIterator(shellState, tableName, iteratorSetting.getIteratorClass());
      }
    } else {
      tableScanIterators = shellState.scanIteratorOptions.get(tableName);
      if (tableScanIterators == null) {
        Shell.log.debug("Found no scan iterators to set");
        return;
      }
    }

    Shell.log.debug("Found {} scan iterators to set", tableScanIterators.size());

    for (IteratorSetting setting : tableScanIterators) {
      Shell.log.debug("Setting scan iterator {} at priority {} using class name {}",
          setting.getName(), setting.getPriority(), setting.getIteratorClass());
      for (Entry<String,String> option : setting.getOptions().entrySet()) {
        Shell.log.debug("Setting option for {}: {}={}", setting.getName(), option.getKey(),
            option.getValue());
      }
      scanner.addScanIterator(setting);
    }
  }

  protected void printRecords(final CommandLine cl, final Shell shellState, FormatterConfig config,
      final Iterable<Entry<Key,Value>> scanner, final Class<? extends Formatter> formatter,
      PrintFile outFile) throws IOException {
    if (outFile == null) {
      shellState.printRecords(scanner, config, !cl.hasOption(disablePaginationOpt.getOpt()),
          formatter);
    } else {
      shellState.printRecords(scanner, config, !cl.hasOption(disablePaginationOpt.getOpt()),
          formatter, outFile);
    }
  }

  protected ScanInterpreter getInterpreter(final CommandLine cl, final String tableName,
      final Shell shellState) throws Exception {

    Class<? extends ScanInterpreter> clazz = null;
    try {
      if (cl.hasOption(interpreterOpt.getOpt())) {
        Shell.log
            .warn("Scan Interpreter option is deprecated and will be removed in a future version.");

        clazz = ClassLoaderUtil.loadClass(cl.getOptionValue(interpreterOpt.getOpt()),
            ScanInterpreter.class);
      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
        Shell.log
            .warn("Scan Interpreter option is deprecated and will be removed in a future version.");

        clazz = ClassLoaderUtil.loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()),
            ScanInterpreter.class);
      }
    } catch (ClassNotFoundException e) {
      Shell.log.error("Interpreter class could not be loaded.", e);
    }

    if (clazz == null)
      clazz = InterpreterCommand.getCurrentInterpreter(tableName, shellState);

    if (clazz == null)
      clazz = DefaultScanInterpreter.class;

    return clazz.getDeclaredConstructor().newInstance();
  }

  protected Class<? extends Formatter> getFormatter(final CommandLine cl, final String tableName,
      final Shell shellState) throws IOException {

    try {
      if (cl.hasOption(formatterOpt.getOpt())) {
        Shell.log.warn("Formatter option is deprecated and will be removed in a future version.");

        return shellState.getClassLoader(cl, shellState)
            .loadClass(cl.getOptionValue(formatterOpt.getOpt())).asSubclass(Formatter.class);
      } else if (cl.hasOption(formatterInterpeterOpt.getOpt())) {
        Shell.log.warn("Formatter option is deprecated and will be removed in a future version.");

        return shellState.getClassLoader(cl, shellState)
            .loadClass(cl.getOptionValue(formatterInterpeterOpt.getOpt()))
            .asSubclass(Formatter.class);
      }
    } catch (Exception e) {
      Shell.log.error("Formatter class could not be loaded.", e);
    }

    return shellState.getFormatter(tableName);
  }

  protected void fetchColumns(final CommandLine cl, final ScannerBase scanner,
      final ScanInterpreter formatter) throws UnsupportedEncodingException {
    if (cl.hasOption(scanOptColumns.getOpt())) {
      for (String a : cl.getOptionValue(scanOptColumns.getOpt()).split(",")) {
        final String[] sa = a.split(":", 2);
        if (sa.length == 1) {
          scanner.fetchColumnFamily(
              formatter.interpretColumnFamily(new Text(a.getBytes(Shell.CHARSET))));
        } else {
          scanner.fetchColumn(
              formatter.interpretColumnFamily(new Text(sa[0].getBytes(Shell.CHARSET))),
              formatter.interpretColumnQualifier(new Text(sa[1].getBytes(Shell.CHARSET))));
        }
      }
    }
  }

  protected Range getRange(final CommandLine cl, final ScanInterpreter formatter)
      throws UnsupportedEncodingException {
    if ((cl.hasOption(OptUtil.START_ROW_OPT) || cl.hasOption(OptUtil.END_ROW_OPT))
        && cl.hasOption(scanOptRow.getOpt())) {
      // did not see a way to make commons cli do this check... it has mutually exclusive options
      // but does not support the or
      throw new IllegalArgumentException("Options -" + scanOptRow.getOpt() + " AND (-"
          + OptUtil.START_ROW_OPT + " OR -" + OptUtil.END_ROW_OPT + ") are mutually exclusive ");
    }

    if (cl.hasOption(scanOptRow.getOpt())) {
      return new Range(formatter
          .interpretRow(new Text(cl.getOptionValue(scanOptRow.getOpt()).getBytes(Shell.CHARSET))));
    } else {
      Text startRow = OptUtil.getStartRow(cl);
      if (startRow != null)
        startRow = formatter.interpretBeginRow(startRow);
      Text endRow = OptUtil.getEndRow(cl);
      if (endRow != null)
        endRow = formatter.interpretEndRow(endRow);
      final boolean startInclusive = !cl.hasOption(optStartRowExclusive.getOpt());
      final boolean endInclusive = !cl.hasOption(optEndRowExclusive.getOpt());
      return new Range(startRow, startInclusive, endRow, endInclusive);
    }
  }

  protected Authorizations getAuths(final CommandLine cl, final Shell shellState)
      throws AccumuloSecurityException, AccumuloException {
    final String user = shellState.getAccumuloClient().whoami();
    Authorizations auths =
        shellState.getAccumuloClient().securityOperations().getUserAuthorizations(user);
    if (cl.hasOption(scanOptAuths.getOpt())) {
      auths = ScanCommand.parseAuthorizations(cl.getOptionValue(scanOptAuths.getOpt()));
    }
    return auths;
  }

  static Authorizations parseAuthorizations(final String field) {
    if (field == null || field.isEmpty()) {
      return Authorizations.EMPTY;
    }
    return new Authorizations(field.split(","));
  }

  @Override
  public String description() {
    return "scans the table, and displays the resulting records";
  }

  @Override
  public Options getOptions() {
    final Options o = new Options();

    scanOptAuths = new Option("s", "scan-authorizations", true,
        "scan authorizations (all user auths are used if this argument is not specified)");
    optStartRowExclusive = new Option("be", "begin-exclusive", false,
        "make start row exclusive (by default it's inclusive)");
    optStartRowExclusive.setArgName("begin-exclusive");
    optEndRowExclusive = new Option("ee", "end-exclusive", false,
        "make end row exclusive (by default it's inclusive)");
    optEndRowExclusive.setArgName("end-exclusive");
    scanOptRow = new Option("r", "row", true, "row to scan");
    scanOptColumns = new Option("c", "columns", true, "comma-separated columns");
    timestampOpt = new Option("st", "show-timestamps", false, "display timestamps");
    disablePaginationOpt = new Option("np", "no-pagination", false, "disable pagination of output");
    showFewOpt = new Option("f", "show-few", true, "show only a specified number of characters");
    formatterOpt =
        new Option("fm", "formatter", true, "fully qualified name of the formatter class to use");
    interpreterOpt = new Option("i", "interpreter", true,
        "fully qualified name of the interpreter class to use");
    formatterInterpeterOpt = new Option("fi", "fmt-interpreter", true,
        "fully qualified name of a class that is a formatter and interpreter");
    timeoutOption = new Option(null, "timeout", true,
        "time before scan should fail if no data is returned. If no unit is"
            + " given assumes seconds. Units d,h,m,s,and ms are supported. e.g. 30s" + " or 100ms");
    outputFileOpt = new Option("o", "output", true, "local file to write the scan output to");
    sampleOpt = new Option(null, "sample", false, "Show sample");
    contextOpt = new Option("cc", "context", true, "name of the classloader context");
    executionHintsOpt = new Option(null, "execution-hints", true, "Execution hints map");

    scanOptAuths.setArgName("comma-separated-authorizations");
    scanOptRow.setArgName("row");
    scanOptColumns
        .setArgName("<columnfamily>[:<columnqualifier>]{,<columnfamily>[:<columnqualifier>]}");
    showFewOpt.setRequired(false);
    showFewOpt.setArgName("int");
    formatterOpt.setArgName("className");
    timeoutOption.setArgName("timeout");
    outputFileOpt.setArgName("file");
    contextOpt.setArgName("context");
    executionHintsOpt.setArgName("<key>=<value>{,<key>=<value>}");

    profileOpt = new Option("pn", "profile", true, "iterator profile name");
    profileOpt.setArgName("profile");

    o.addOption(scanOptAuths);
    o.addOption(scanOptRow);
    optStartRowInclusive =
        new Option(OptUtil.START_ROW_OPT, "begin-row", true, "begin row (inclusive)");
    optStartRowInclusive.setArgName("begin-row");
    o.addOption(optStartRowInclusive);
    o.addOption(OptUtil.endRowOpt());
    o.addOption(optStartRowExclusive);
    o.addOption(optEndRowExclusive);
    o.addOption(scanOptColumns);
    o.addOption(timestampOpt);
    o.addOption(disablePaginationOpt);
    o.addOption(OptUtil.tableOpt("table to be scanned"));
    o.addOption(showFewOpt);
    o.addOption(formatterOpt);
    o.addOption(interpreterOpt);
    o.addOption(formatterInterpeterOpt);
    o.addOption(timeoutOption);
    if (Arrays.asList(ScanCommand.class.getName(), GrepCommand.class.getName(),
        EGrepCommand.class.getName()).contains(this.getClass().getName())) {
      // supported subclasses must handle the output file option properly
      // only add this option to commands which handle it correctly
      o.addOption(outputFileOpt);
    }
    o.addOption(profileOpt);
    o.addOption(sampleOpt);
    o.addOption(contextOpt);
    o.addOption(executionHintsOpt);

    return o;
  }

  @Override
  public int numArgs() {
    return 0;
  }

  protected PrintFile getOutputFile(final CommandLine cl) throws FileNotFoundException {
    final String outputFile = cl.getOptionValue(outputFileOpt.getOpt());
    return (outputFile == null ? null : new PrintFile(outputFile));
  }
}
