// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.build.lib.shell;

import java.util.List;

/**
 * Utility functions for Bourne shell commands, including escaping and
 * tokenizing.
 */
public abstract class ShellUtils {

  private ShellUtils() {}

  /**
   * Characters that have no special meaning to the shell.
   */
  private static final String SAFE_PUNCTUATION = "@%-_+:,./";

  /**
   * Quotes a word so that it can be used, without further quoting,
   * as an argument (or part of an argument) in a shell command.
   */
  public static String shellEscape(String word) {
    int len = word.length();
    if (len == 0) {
      // Empty string is a special case: needs to be quoted to ensure that it gets
      // treated as a separate argument.
      return "''";
    }
    for (int ii = 0; ii < len; ii++) {
      char c = word.charAt(ii);
      // We do this positively so as to be sure we don't inadvertently forget
      // any unsafe characters.
      if (!Character.isLetterOrDigit(c) && SAFE_PUNCTUATION.indexOf(c) == -1) {
        // replace() actually means "replace all".
        return "'" + word.replace("'", "'\\''") + "'";
      }
    }
    return word;
  }

  /**
   * Given an argv array such as might be passed to execve(2), returns a string
   * that can be copied and pasted into a Bourne shell for a similar effect.
   */
  public static String prettyPrintArgv(List<String> argv) {
    StringBuilder buf = new StringBuilder();
    for (String arg: argv) {
      if (buf.length() > 0) {
        buf.append(' ');
      }
      buf.append(shellEscape(arg));
    }
    return buf.toString();
  }


  /**
   * Thrown by tokenize method if there is an error
   */
  public static class TokenizationException extends Exception {
    TokenizationException(String message) {
      super(message);
    }
  }

  /**
   * Populates the passed list of command-line options extracted from {@code
   * optionString}, which is a string containing multiple options, delimited in
   * a Bourne shell-like manner.
   *
   * @param options the list to be populated with tokens.
   * @param optionString the string to be tokenized.
   * @throws TokenizationException if there was an error (such as an
   * unterminated quotation).
   */
  public static void tokenize(List<String> options, String optionString)
      throws TokenizationException {
    // See test suite for examples.
    //
    // Note: backslash escapes the following character, except within a
    // single-quoted region where it is literal.

    StringBuilder token = new StringBuilder();
    boolean forceToken = false;
    char quotation = '\0'; // NUL, '\'' or '"'
    for (int ii = 0, len = optionString.length(); ii < len; ii++) {
      char c = optionString.charAt(ii);
      if (quotation != '\0') { // in quotation
        if (c == quotation) { // end of quotation
          quotation = '\0';
        } else if (c == '\\' && quotation == '"') { // backslash in "-quotation
          if (++ii == len) {
            throw new TokenizationException("backslash at end of string");
          }
          c = optionString.charAt(ii);
          if (c != '\\' && c != '"') {
            token.append('\\');
          }
          token.append(c);
        } else { // regular char, in quotation
          token.append(c);
        }
      } else { // not in quotation
        if (c == '\'' || c == '"') { // begin single/double quotation
          quotation = c;
          forceToken = true;
        } else if (c == ' ' || c == '\t') { // space, not quoted
          if (forceToken || token.length() > 0) {
            options.add(token.toString());
            token = new StringBuilder();
            forceToken = false;
          }
        } else if (c == '\\') { // backslash, not quoted
          if (++ii == len) {
            throw new TokenizationException("backslash at end of string");
          }
          token.append(optionString.charAt(ii));
        } else { // regular char, not quoted
          token.append(c);
        }
      }
    }
    if (quotation != '\0') {
      throw new TokenizationException("unterminated quotation");
    }
    if (forceToken || token.length() > 0) {
      options.add(token.toString());
    }
  }

}
