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

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.Vector;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import org.apache.tools.ant.BuildException;

/**
 * A set of helper methods related to string manipulation.
 *
 */
public final class StringUtils {
    private static final long KILOBYTE = 1024;
    private static final long MEGABYTE = KILOBYTE * 1024;
    private static final long GIGABYTE = MEGABYTE * 1024;
    private static final long TERABYTE = GIGABYTE * 1024;
    private static final long PETABYTE = TERABYTE * 1024;

    /**
     * constructor to stop anyone instantiating the class
     */
    private StringUtils() {
    }

    /** the line separator for this OS */
    public static final String LINE_SEP = System.getProperty("line.separator");

    /**
     * Splits up a string into a list of lines. It is equivalent
     * to <tt>split(data, '\n')</tt>.
     * @param data the string to split up into lines.
     * @return the list of lines available in the string.
     */
    public static Vector<String> lineSplit(String data) {
        return split(data, '\n');
    }

    /**
     * Splits up a string where elements are separated by a specific
     * character and return all elements.
     * @param data the string to split up.
     * @param ch the separator character.
     * @return the list of elements.
     */
    public static Vector<String> split(String data, int ch) {
        Vector<String> elems = new Vector<String>();
        int pos = -1;
        int i = 0;
        while ((pos = data.indexOf(ch, i)) != -1) {
            String elem = data.substring(i, pos);
            elems.addElement(elem);
            i = pos + 1;
        }
        elems.addElement(data.substring(i));
        return elems;
    }

    /**
     * Replace occurrences into a string.
     * @param data the string to replace occurrences into
     * @param from the occurrence to replace.
     * @param to the occurrence to be used as a replacement.
     * @return the new string with replaced occurrences.
     * @deprecated Use {@link String#replace(CharSequence, CharSequence)} now.
     */
    public static String replace(String data, String from, String to) {
        return data.replace(from, to);
    }

    /**
     * Convenient method to retrieve the full stacktrace from a given exception.
     * @param t the exception to get the stacktrace from.
     * @return the stacktrace from the given exception.
     */
    public static String getStackTrace(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        t.printStackTrace(pw);
        pw.flush();
        pw.close();
        return sw.toString();
    }

    /**
     * Checks that a string buffer ends up with a given string. It may sound
     * trivial with the existing
     * JDK API but the various implementation among JDKs can make those
     * methods extremely resource intensive
     * and perform poorly due to massive memory allocation and copying. See
     * @param buffer the buffer to perform the check on
     * @param suffix the suffix
     * @return  <code>true</code> if the character sequence represented by the
     *          argument is a suffix of the character sequence represented by
     *          the StringBuffer object; <code>false</code> otherwise. Note that the
     *          result will be <code>true</code> if the argument is the
     *          empty string.
     */
    public static boolean endsWith(StringBuffer buffer, String suffix) {
        if (suffix.length() > buffer.length()) {
            return false;
        }
        // this loop is done on purpose to avoid memory allocation performance
        // problems on various JDKs
        // StringBuffer.lastIndexOf() was introduced in jdk 1.4 and
        // implementation is ok though does allocation/copying
        // StringBuffer.toString().endsWith() does massive memory
        // allocation/copying on JDK 1.5
        // See http://issues.apache.org/bugzilla/show_bug.cgi?id=37169
        int endIndex = suffix.length() - 1;
        int bufferIndex = buffer.length() - 1;
        while (endIndex >= 0) {
            if (buffer.charAt(bufferIndex) != suffix.charAt(endIndex)) {
                return false;
            }
            bufferIndex--;
            endIndex--;
        }
        return true;
    }

    /**
     * xml does not do "c" like interpretation of strings.
     * i.e. \n\r\t etc.
     * this method processes \n, \r, \t, \f, \\
     * also subs \s -&gt; " \n\r\t\f"
     * a trailing '\' will be ignored
     *
     * @param input raw string with possible embedded '\'s
     * @return converted string
     * @since Ant 1.7
     */
    public static String resolveBackSlash(String input) {
        StringBuffer b = new StringBuffer();
        boolean backSlashSeen = false;
        for (int i = 0; i < input.length(); ++i) {
            char c = input.charAt(i);
            if (!backSlashSeen) {
                if (c == '\\') {
                    backSlashSeen = true;
                } else {
                    b.append(c);
                }
            } else {
                switch (c) {
                    case '\\':
                        b.append((char) '\\');
                        break;
                    case 'n':
                        b.append((char) '\n');
                        break;
                    case 'r':
                        b.append((char) '\r');
                        break;
                    case 't':
                        b.append((char) '\t');
                        break;
                    case 'f':
                        b.append((char) '\f');
                        break;
                    case 's':
                        b.append(" \t\n\r\f");
                        break;
                    default:
                        b.append(c);
                }
                backSlashSeen = false;
            }
        }
        return b.toString();
    }

    /**
     * Takes a human readable size representation eg 10K
     * a long value. Doesn't support 1.1K or other rational values.
     * @param humanSize the amount as a human readable string.
     * @return a long value representation
     * @throws Exception if there is a problem.
     * @since Ant 1.7
     */
    public static long parseHumanSizes(String humanSize) throws Exception {
        long factor = 1L;
        char s = humanSize.charAt(0);
        switch (s) {
            case '+':
                humanSize = humanSize.substring(1);
                break;
            case '-':
                factor = -1L;
                humanSize = humanSize.substring(1);
                break;
            default:
                break;
        }
        //last character isn't a digit
        char c = humanSize.charAt(humanSize.length() - 1);
        if (!Character.isDigit(c)) {
            int trim = 1;
            switch (c) {
                case 'K':
                    factor *= KILOBYTE;
                    break;
                case 'M':
                    factor *= MEGABYTE;
                    break;
                case 'G':
                    factor *= GIGABYTE;
                    break;
                case 'T':
                    factor *= TERABYTE;
                    break;
                case 'P':
                    factor *= PETABYTE;
                    break;
                default:
                    trim = 0;
            }
            humanSize = humanSize.substring(0, humanSize.length() - trim);
        }
        try {
            return factor * Long.parseLong(humanSize);
        } catch (NumberFormatException e) {
            throw new BuildException("Failed to parse \"" + humanSize + "\"", e);
        }
    }

    /**
     * Removes the suffix from a given string, if the string contains
     * that suffix.
     * @param string String for check
     * @param suffix Suffix to remove
     * @return the <i>string</i> with the <i>suffix</i>
     */
    public static String removeSuffix(String string, String suffix) {
        if (string.endsWith(suffix)) {
            return string.substring(0, string.length() - suffix.length());
        } else {
            return string;
        }
    }

    /**
     * Removes the prefix from a given string, if the string contains
     * that prefix.
     * @param string String for check
     * @param prefix Prefix to remove
     * @return the <i>string</i> with the <i>prefix</i>
     */
    public static String removePrefix(String string, String prefix) {
        if (string.startsWith(prefix)) {
            return string.substring(prefix.length());
        } else {
            return string;
        }
    }
    
    /**
     * Joins the string representation of the elements of a collection to 
     * a joined string with a given separator.
     * @param collection Collection of the data to be joined (may be null)
     * @param separator Separator between elements (may be null)
     * @return the joined string
     */
    public static String join(Collection<?> collection, CharSequence separator) {
        if (collection == null) {
            return "";
        }
        return collection.stream().map( o -> String.valueOf(o) ).collect(joining(separator));
    }

    /**
     * Joins the string representation of the elements of an array to 
     * a joined string with a given separator.
     * @param array Array of the data to be joined (may be null)
     * @param separator Separator between elements (may be null)
     * @return the joined string
     */
    public static String join(Object[] array, CharSequence separator) {
        if (array == null) {
            return "";
        }
        return join(Arrays.asList(array), separator);
    }

    private static Collector<CharSequence,?,String> joining(CharSequence separator) {
        return separator == null ? Collectors.joining() : Collectors.joining(separator);
    }
}
