/**
 * 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.tajo.util;

import com.google.common.base.Function;
import io.netty.util.CharsetUtil;
import org.apache.commons.lang.CharUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.hadoop.util.Shell;
import org.apache.hadoop.util.ShutdownHookManager;
import org.apache.hadoop.util.SignalLogger;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import java.util.Arrays;
import java.util.BitSet;

public class StringUtils {

  /**
   * Priority of the StringUtils shutdown hook.
   */
  public static final int SHUTDOWN_HOOK_PRIORITY = 0;

  /**
   *
   * Given the time in long milliseconds, returns a
   * String in the format X hrs, Y mins, S sec, M msecs
   *
   * @param timeDiff The time difference to format
   */
  public static String formatTime(long timeDiff){
    StringBuilder buf = new StringBuilder();
    long hours = timeDiff / (60*60*1000);
    long rem = (timeDiff % (60*60*1000));
    long minutes =  rem / (60*1000);
    rem = rem % (60*1000);
    long seconds = rem / 1000;

    if (hours != 0){
      buf.append(hours);
      buf.append(" hrs, ");
    }
    if (minutes != 0){
      buf.append(minutes);
      buf.append(" mins, ");
    }

    if (seconds != 0) {
      buf.append(seconds);
      buf.append(" sec");
    }

    if (timeDiff < 1000) {
      buf.append(timeDiff);
      buf.append(" msec");
    }
    return buf.toString();
  }
  /**
   * Check Seven-bit ASCII
   */
  public static boolean isPureAscii(String v) {
    // get thread-safe encoder
    CharsetEncoder asciiEncoder = CharsetUtil.getEncoder(CharsetUtil.US_ASCII);
    return asciiEncoder.canEncode(v);
  }

  public static String quote(String str) {
    return "'" + str + "'";
  }

  public static String doubleQuote(String str) {
    return "\"" + str + "\"";
  }

  public static boolean isPartOfAnsiSQLIdentifier(char character) {
    return
        isLowerCaseAlphabet(character) ||
        isUpperCaseAlphabet(character) ||
        isDigit(character)             ||
        isUndersscore(character);
  }

  public static boolean isUndersscore(char character) {
    return character == '_';
  }

  public static boolean isLowerCaseAlphabet(char character) {
    return 'a' <= character && character <= 'z';
  }

  public static boolean isUpperCaseAlphabet(char character) {
    return 'A' <= character && character <= 'Z';
  }

  public static boolean isDigit(char character) {
    return '0' <= character && character <= '9';
  }

  private static final String REGEX_SPECIAL_CHARACTERS = "([.*${}?|\\^\\-\\[\\]])";
  public static String escapeRegexp(String literal) {
    return literal.replaceAll(REGEX_SPECIAL_CHARACTERS, "\\\\$1");
  }

  private static final String LIKE_SPECIAL_CHARACTERS = "([_%])";
  public static String escapeLike(String literal) {
    return literal.replaceAll(LIKE_SPECIAL_CHARACTERS, "\\\\$1");
  }

  /**
   * Return a message for logging.
   * @param prefix prefix keyword for the message
   * @param msg content of the message
   * @return a message for logging
   */
  private static String toStartupShutdownString(String prefix, String [] msg) {
    StringBuilder b = new StringBuilder(prefix);
    b.append("\n/************************************************************");
    for(String s : msg)
      b.append("\n" + prefix + s);
    b.append("\n************************************************************/");
    return b.toString();
  }

  /**
   * Print a log message for starting up and shutting down
   * @param clazz the class of the server
   * @param args arguments
   * @param LOG the target log object
   */
  public static void startupShutdownMessage(Class<?> clazz, String[] args,
                                            final org.apache.commons.logging.Log LOG) {
    final String hostname = org.apache.hadoop.net.NetUtils.getHostname();
    final String classname = clazz.getSimpleName();
    LOG.info(
        toStartupShutdownString("STARTUP_MSG: ", new String[] {
            "Starting " + classname,
            "  host = " + hostname,
            "  args = " + Arrays.asList(args),
            "  version = " + org.apache.tajo.util.VersionInfo.getVersion(),
            "  classpath = " + System.getProperty("java.class.path"),
            "  build = " + org.apache.tajo.util.VersionInfo.getUrl() + " -r "
                + org.apache.tajo.util.VersionInfo.getRevision()
                + "; compiled by '" + org.apache.tajo.util.VersionInfo.getUser()
                + "' on " + org.apache.tajo.util.VersionInfo.getDate(),
            "  java = " + System.getProperty("java.version") }
        )
    );

    if (SystemUtils.IS_OS_UNIX) {
      try {
        SignalLogger.INSTANCE.register(LOG);
      } catch (Throwable t) {
        LOG.warn("failed to register any UNIX signal loggers: ", t);
      }
    }
    ShutdownHookManager.get().addShutdownHook(
        new Runnable() {
          @Override
          public void run() {
            LOG.info(toStartupShutdownString("SHUTDOWN_MSG: ", new String[]{
                "Shutting down " + classname + " at " + hostname}));
          }
        }, SHUTDOWN_HOOK_PRIORITY);
  }

  public static String unicodeEscapedDelimiter(String value) {
    try {
      String delimiter = StringEscapeUtils.unescapeJava(value);
      StringBuilder builder = new StringBuilder();
      for (char achar : delimiter.toCharArray()) {
        builder.append(unicodeEscapedDelimiter(achar));
      }
      return builder.toString();
    } catch (Throwable e) {
    }
    return value;
  }

  public static String unicodeEscapedDelimiter(char c) {
    return CharUtils.unicodeEscaped(c);
  }

  /**
   * The following lines of code that deals with escape characters is mostly copied from HIVE's FileUtils.java 
   */

  static BitSet charToEscape = new BitSet(128);
  static {
    for (char c = 0; c < ' '; c++) {
      charToEscape.set(c);
    }

    /**
     * ASCII 01-1F are HTTP control characters that need to be escaped.
     * \u000A and \u000D are \n and \r, respectively.
     */
    char[] clist = new char[] {'\u0001', '\u0002', '\u0003', '\u0004',
        '\u0005', '\u0006', '\u0007', '\u0008', '\u0009', '\n', '\u000B',
        '\u000C', '\r', '\u000E', '\u000F', '\u0010', '\u0011', '\u0012',
        '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019',
        '\u001A', '\u001B', '\u001C', '\u001D', '\u001E', '\u001F',
        '"', '#', '%', '\'', '*', '/', ':', '=', '?', '\\', '\u007F', '{',
        '[', ']', '^'};

    for (char c : clist) {
      charToEscape.set(c);
    }

    if(Shell.WINDOWS){
      // On windows, following chars need to be escaped as well
      char [] winClist = {' ', '<','>','|'};
      for (char c : winClist) {
        charToEscape.set(c);
      }
    }
  }

  static boolean needsEscaping(char c) {
    return c >= 0 && c < charToEscape.size() && charToEscape.get(c);
  }

  public static String escapePathName(String path) {
    return escapePathName(path, null);
  }

  /**
   * Escapes a path name.
   * @param path The path to escape.
   * @param defaultPath
   * The default name for the path, if the given path is empty or null.
   * @return An escaped path name.
   */
  public static String escapePathName(String path, String defaultPath) {
    if (path == null || path.length() == 0) {
      if (defaultPath == null) {
        return "__TAJO_DEFAULT_PARTITION__";
      } else {
        return defaultPath;
      }
    }

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < path.length(); i++) {
      char c = path.charAt(i);
      if (needsEscaping(c)) {
        sb.append('%');
        sb.append(String.format("%1$02X", (int) c));
      } else {
        sb.append(c);
      }
    }
    return sb.toString();
  }

  public static String unescapePathName(String path) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < path.length(); i++) {
      char c = path.charAt(i);
      if (c == '%' && i + 2 < path.length()) {
        int code = -1;
        try {
          code = Integer.valueOf(path.substring(i + 1, i + 3), 16);
        } catch (Exception e) {
          code = -1;
        }
        if (code >= 0) {
          sb.append((char) code);
          i += 2;
          continue;
        }
      }
      sb.append(c);
    }
    return sb.toString();
  }

  public static char[][] padChars(char []...bytes) {
    char[] startChars = bytes[0];
    char[] endChars = bytes[1];

    char[][] padded = new char[2][];
    int max = Math.max(startChars.length, endChars.length);

    padded[0] = new char[max];
    padded[1] = new char[max];

    System.arraycopy(startChars, 0, padded[0], 0, startChars.length);
    for (int i = startChars.length; i < max; i++) {
      padded[0][i] = 0;
    }
    System.arraycopy(endChars, 0, padded[1], 0, endChars.length);
    for (int i = endChars.length; i < max; i++) {
      padded[1][i] = 0;
    }

    return padded;
  }
  
  public static char[] convertBytesToChars(byte[] src, Charset charset) {
    CharsetDecoder decoder = charset.newDecoder();
    char[] resultArray = new char[(int) (src.length * decoder.maxCharsPerByte())];
    
    if (src.length != 0) {
      ByteBuffer byteBuffer = ByteBuffer.wrap(src);
      CharBuffer charBuffer = CharBuffer.wrap(resultArray);
      
      decoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
      decoder.reset();
      
      CoderResult coderResult = decoder.decode(byteBuffer, charBuffer, true);
      if (coderResult.isUnderflow()) {
        coderResult = decoder.flush(charBuffer);
        
        if (coderResult.isUnderflow()) {
          if (resultArray.length != charBuffer.position()) {
            resultArray = Arrays.copyOf(resultArray, charBuffer.position());
          }
        }
      }
    }
    
    return resultArray;
  }
  
  public static byte[] convertCharsToBytes(char[] src, Charset charset) {
    CharsetEncoder encoder = charset.newEncoder();
    byte[] resultArray = new byte[(int) (src.length * encoder.maxBytesPerChar())];
    
    if (src.length != 0) {
      CharBuffer charBuffer = CharBuffer.wrap(src);
      ByteBuffer byteBuffer = ByteBuffer.wrap(resultArray);
      
      encoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE);
      encoder.reset();
      
      CoderResult coderResult = encoder.encode(charBuffer, byteBuffer, true);
      if (coderResult.isUnderflow()) {
        coderResult = encoder.flush(byteBuffer);
        
        if (coderResult.isUnderflow()) {
          if (resultArray.length != byteBuffer.position()) {
            resultArray = Arrays.copyOf(resultArray, byteBuffer.position());
          }
        }
      }
    }
    
    return resultArray;
  }

  /**
   * Concatenate all objects' string with a delimiter string
   *
   * @param objects Iterable objects
   * @param delimiter Delimiter string
   * @return A joined string
   */
  public static String join(Iterable objects, String delimiter) {
    boolean first = true;
    StringBuilder sb = new StringBuilder();
    for(Object object : objects) {
      if (first) {
        first = false;
      } else {
        sb.append(delimiter);
      }

      sb.append(object.toString());
    }

    return sb.toString();
  }

  /**
   * Concatenate all objects' string with the delimiter ", "
   *
   * @param objects Iterable objects
   * @return A joined string
   */
  public static String join(Object[] objects) {
    return join(objects, ", ");
  }

  /**
   * Concatenate all objects' string with the delimiter ", "
   *
   * @param objects Iterable objects
   * @return A joined string
   */
  public static String join(Object[] objects, String delimiter) {
    return join(objects, delimiter, 0, objects.length);
  }

  /**
   * Concatenate all objects' string with a delimiter string
   *
   * @param objects object array
   * @param delimiter Delimiter string
   * @param startIndex the begin index to join
   * @return A joined string
   */
  public static String join(Object[] objects, String delimiter, int startIndex) {
    return join(objects, delimiter, startIndex, objects.length);
  }

  /**
   * Concatenate all objects' string with a delimiter string
   *
   * @param objects object array
   * @param delimiter Delimiter string
   * @param startIndex the begin index to join
   * @param length the number of columns to be joined
   * @return A joined string
   */
  public static String join(Object[] objects, String delimiter, int startIndex, int length) {
    return join(objects, delimiter, startIndex, length, new Function<Object, String>() {
      @Override
      public String apply(Object input) {
        return input.toString();
      }
    });
  }


  /**
   * Concatenate all objects' string with a delimiter string
   *
   * @param objects object array
   * @param delimiter Delimiter string
   * @param f convert from a type to string
   * @return A joined string
   */
  public static <T> String join(T [] objects, String delimiter, Function<T, String> f) {
    return join(objects, delimiter, 0, objects.length, f);
  }

  public static <T> String join(T [] objects, String delimiter, int startIndex, int length, Function<T, String> f) {
    boolean first = true;
    StringBuilder sb = new StringBuilder();
    int endIndex = startIndex + length;
    for(int i = startIndex; i + startIndex < endIndex; i++) {
      if (first) {
        first = false;
      } else {
        sb.append(delimiter);
      }

      sb.append(f.apply(objects[i]));
    }

    return sb.toString();
  }

  /**
   * <p>Checks if a String is empty ("") or null.</p>
   *
   * <pre>
   * StringUtils.isEmpty(null)      = true
   * StringUtils.isEmpty("")        = true
   * StringUtils.isEmpty(" ")       = false
   * StringUtils.isEmpty("bob")     = false
   * StringUtils.isEmpty("  bob  ") = false
   * </pre>
   *
   * <p>NOTE: This method changed in Lang version 2.0.
   * It no longer trims the String.
   * That functionality is available in isBlank().</p>
   *
   * @param str  the String to check, may be null
   * @return <code>true</code> if the String is empty or null
   */
  public static boolean isEmpty(String str) {
    return str == null || str.length() == 0;
  }
}
