/*
 *  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
 *
 *      https://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.filters;

import java.io.IOException;
import java.io.Reader;
import java.util.Vector;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.types.RegularExpression;
import org.apache.tools.ant.types.Substitution;
import org.apache.tools.ant.util.LineTokenizer;
import org.apache.tools.ant.util.StringUtils;
import org.apache.tools.ant.util.Tokenizer;
import org.apache.tools.ant.util.regexp.Regexp;
import org.apache.tools.ant.util.regexp.RegexpUtil;

/**
 * This splits up input into tokens and passes
 * the tokens to a sequence of filters.
 *
 * @since Ant 1.6
 * @see BaseFilterReader
 * @see ChainableReader
 * @see org.apache.tools.ant.DynamicConfigurator
 */
public class TokenFilter extends BaseFilterReader
    implements ChainableReader {
    /**
     * string filters implement this interface
     */
    public interface Filter {
        /**
         * filter and/of modify a string
         *
         * @param string the string to filter
         * @return the modified string or null if the
         *         string did not pass the filter
         */
        String filter(String string);
    }


    /** string filters */
    private Vector<Filter> filters = new Vector<>();
    /** the tokenizer to use on the input stream */
    private Tokenizer tokenizer = null;
    /** the output token termination */
    private String delimOutput = null;
    /** the current string token from the input stream */
    private String line    = null;
    /** the position in the current string token */
    private int    linePos = 0;

    /**
     * Constructor for "dummy" instances.
     *
     * @see BaseFilterReader#BaseFilterReader()
     */
    public TokenFilter() {
        super();
    }

    /**
     * Creates a new filtered reader.
     *
     * @param in A Reader object providing the underlying stream.
     *           Must not be <code>null</code>.
     */
    public TokenFilter(final Reader in) {
        super(in);
    }


    /**
     * Returns the next character in the filtered stream, only including
     * lines from the original stream which match all of the specified
     * regular expressions.
     *
     * @return the next character in the resulting stream, or -1
     * if the end of the resulting stream has been reached
     *
     * @exception IOException if the underlying stream throws an IOException
     * during reading
     */

    public int read() throws IOException {
        if (tokenizer == null) {
            tokenizer = new LineTokenizer();
        }
        while (line == null || line.isEmpty()) {
            line = tokenizer.getToken(in);
            if (line == null) {
                return -1;
            }
            for (Filter filter : filters) {
                line = filter.filter(line);
                if (line == null) {
                    break;
                }
            }
            linePos = 0;
            if (line != null && !tokenizer.getPostToken().isEmpty()) {
                if (delimOutput != null) {
                    line += delimOutput;
                } else {
                    line += tokenizer.getPostToken();
                }
            }
        }
        int ch = line.charAt(linePos);
        linePos++;
        if (linePos == line.length()) {
            line = null;
        }
        return ch;
    }

    /**
     * Creates a new TokenFilter using the passed in
     * Reader for instantiation.
     *
     * @param reader A Reader object providing the underlying stream.
     *
     * @return a new filter based on this configuration
     */

    public final Reader chain(final Reader reader) {
        TokenFilter newFilter = new TokenFilter(reader);
        newFilter.filters = filters;
        newFilter.tokenizer = tokenizer;
        newFilter.delimOutput = delimOutput;
        newFilter.setProject(getProject());
        return newFilter;
    }

    /**
     * set the output delimiter.
     * @param delimOutput replaces the delim string returned by the
     *                    tokenizer, if present.
     */

    public void setDelimOutput(String delimOutput) {
        this.delimOutput = resolveBackSlash(delimOutput);
    }

    // -----------------------------------------
    //  Predefined tokenizers
    // -----------------------------------------

    /**
     * add a line tokenizer - this is the default.
     * @param tokenizer the line tokenizer
     */

    public void addLineTokenizer(LineTokenizer tokenizer) {
        add(tokenizer);
    }

    /**
     * add a string tokenizer
     * @param tokenizer the string tokenizer
     */

    public void addStringTokenizer(StringTokenizer tokenizer) {
        add(tokenizer);
    }

    /**
     * add a file tokenizer
     * @param tokenizer the file tokenizer
     */
    public void addFileTokenizer(FileTokenizer tokenizer) {
        add(tokenizer);
    }

    /**
     * add an arbitrary tokenizer
     * @param tokenizer the tokenizer to all, only one allowed
     */

    public void add(Tokenizer tokenizer) {
        if (this.tokenizer != null) {
            throw new BuildException("Only one tokenizer allowed");
        }
        this.tokenizer = tokenizer;
    }

    // -----------------------------------------
    //  Predefined filters
    // -----------------------------------------

    /**
     * replace string filter
     * @param filter the replace string filter
     */
    public void addReplaceString(ReplaceString filter) {
        filters.addElement(filter);
    }

    /**
     * contains string filter
     * @param filter the contains string filter
     */
    public void addContainsString(ContainsString filter) {
        filters.addElement(filter);
    }

    /**
     * replace regex filter
     * @param filter the replace regex filter
     */
    public void addReplaceRegex(ReplaceRegex filter) {
        filters.addElement(filter);
    }

    /**
     * contains regex filter
     * @param filter the contains regex filter
     */
    public void addContainsRegex(ContainsRegex filter) {
        filters.addElement(filter);
    }

    /**
     * trim filter
     * @param filter the trim filter
     */
    public void addTrim(Trim filter) {
        filters.addElement(filter);
    }

    /**
     * ignore blank filter
     * @param filter the ignore blank filter
     */
    public void addIgnoreBlank(IgnoreBlank filter) {
        filters.addElement(filter);
    }

    /**
     * delete chars
     * @param filter the delete characters filter
     */
    public void addDeleteCharacters(DeleteCharacters filter) {
        filters.addElement(filter);
    }

    /**
     * Add an arbitrary filter
     * @param filter the filter to add
     */
    public void add(Filter filter) {
        filters.addElement(filter);
    }


    // --------------------------------------------
    //
    //      Tokenizer Classes (impls moved to oata.util)
    //
    // --------------------------------------------

    /**
     * class to read the complete input into a string
     */
    public static class FileTokenizer
        extends org.apache.tools.ant.util.FileTokenizer {
    }

    /**
     * class to tokenize the input as areas separated
     * by white space, or by a specified list of
     * delim characters. Behaves like java.util.StringTokenizer.
     * if the stream starts with delim characters, the first
     * token will be an empty string (unless the treat delims
     * as tokens flag is set).
     */
    public static class StringTokenizer
        extends org.apache.tools.ant.util.StringTokenizer {
    }

    // --------------------------------------------
    //
    //      Filter classes
    //
    // --------------------------------------------

    /**
     * Abstract class that converts derived filter classes into
     * ChainableReaderFilter's
     */
    public abstract static class ChainableReaderFilter extends ProjectComponent
        implements ChainableReader, Filter {
        private boolean byLine = true;

        /**
         * set whether to use filetokenizer or line tokenizer
         * @param byLine if true use a linetokenizer (default) otherwise
         *               use a filetokenizer
         */
        public void setByLine(boolean byLine) {
            this.byLine = byLine;
        }

        /**
         * Chain a tokenfilter reader to a reader,
         *
         * @param reader the input reader object
         * @return the chained reader object
         */
        public Reader chain(Reader reader) {
            TokenFilter tokenFilter = new TokenFilter(reader);
            if (!byLine) {
                tokenFilter.add(new FileTokenizer());
            }
            tokenFilter.add(this);
            return tokenFilter;
        }
    }

    /**
     * Simple replace string filter.
     */
    public static class ReplaceString extends ChainableReaderFilter {
        private String from;
        private String to;

        /**
         * the from attribute
         *
         * @param from the string to replace
         */
        public void setFrom(String from) {
            this.from = from;
        }

        /**
         * the to attribute
         *
         * @param to the string to replace 'from' with
         */
        public void setTo(String to) {
            this.to = to;
        }

        /**
         * Filter a string 'line' replacing from with to
         * (Copy&amp;Paste from the Replace task)
         * @param line the string to be filtered
         * @return the filtered line
         */
        public String filter(String line) {
            if (from == null) {
                throw new BuildException("Missing from in stringreplace");
            }
            StringBuffer ret = new StringBuffer();
            int start = 0;
            int found = line.indexOf(from);
            while (found >= 0) {
                // write everything up to the from
                if (found > start) {
                    ret.append(line, start, found);
                }

                // write the replacement to
                if (to != null) {
                    ret.append(to);
                }

                // search again
                start = found + from.length();
                found = line.indexOf(from, start);
            }

            // write the remaining characters
            if (line.length() > start) {
                ret.append(line, start, line.length());
            }

            return ret.toString();
        }
    }

    /**
     * Simple filter to filter lines contains strings
     */
    public static class ContainsString extends ProjectComponent
        implements Filter {
        private String contains;

        /**
         * the contains attribute
         * @param contains the string that the token should contain
         */
        public void setContains(String contains) {
            this.contains = contains;
        }

        /**
         * Filter strings that contain the contains attribute
         *
         * @param string the string to be filtered
         * @return null if the string does not contain "contains",
         *              string otherwise
         */
        public String filter(String string) {
            if (contains == null) {
                throw new BuildException("Missing contains in containsstring");
            }
            if (string.contains(contains)) {
                return string;
            }
            return null;
        }
    }

    /**
     * filter to replace regex.
     */
    public static class ReplaceRegex extends ChainableReaderFilter {
        private String             from;
        private String             to;
        private RegularExpression  regularExpression;
        private Substitution       substitution;
        private boolean            initialized = false;
        private String             flags = "";
        private int                options;
        private Regexp             regexp;

        /**
         * the from attribute
         * @param from the regex string
         */
        public void setPattern(String from) {
            this.from = from;
        }
        /**
         * the to attribute
         * @param to the replacement string
         */
        public void setReplace(String to) {
            this.to = to;
        }

        /**
         * @param flags the regex flags
         */
        public void setFlags(String flags) {
            this.flags = flags;
        }

        private void initialize() {
            if (initialized) {
                return;
            }
            options = convertRegexOptions(flags);
            if (from == null) {
                throw new BuildException("Missing pattern in replaceregex");
            }
            regularExpression = new RegularExpression();
            regularExpression.setPattern(from);
            regexp = regularExpression.getRegexp(getProject());
            if (to == null) {
                to = "";
            }
            substitution = new Substitution();
            substitution.setExpression(to);
        }

        /**
         * @param line the string to modify
         * @return the modified string
         */
        public String filter(String line) {
            initialize();

            if (!regexp.matches(line, options)) {
                return line;
            }
            return regexp.substitute(
                line, substitution.getExpression(getProject()), options);
        }
    }

    /**
     * filter to filter tokens matching regular expressions.
     */
    public static class ContainsRegex extends ChainableReaderFilter {
        private String             from;
        private String             to;
        private RegularExpression  regularExpression;
        private Substitution       substitution;
        private boolean            initialized = false;
        private String             flags = "";
        private int                options;
        private Regexp             regexp;


        /**
         * @param from the regex pattern
         */
        public void setPattern(String from) {
            this.from = from;
        }

        /**
         * @param to the replacement string
         */
        public void setReplace(String to) {
            this.to = to;
        }

        /**
         * @param flags the regex flags
         */
        public void setFlags(String flags) {
            this.flags = flags;
        }

        private void initialize() {
            if (initialized) {
                return;
            }
            options = convertRegexOptions(flags);
            if (from == null) {
                throw new BuildException("Missing from in containsregex");
            }
            regularExpression = new RegularExpression();
            regularExpression.setPattern(from);
            regexp = regularExpression.getRegexp(getProject());
            if (to == null) {
                return;
            }
            substitution = new Substitution();
            substitution.setExpression(to);
        }

        /**
         * apply regex and substitution on a string
         * @param string the string to apply filter on
         * @return the filtered string
         */
        public String filter(String string) {
            initialize();
            if (!regexp.matches(string, options)) {
                return null;
            }
            if (substitution == null) {
                return string;
            }
            return regexp.substitute(
                string, substitution.getExpression(getProject()), options);
        }
    }

    /** Filter to trim white space */
    public static class Trim extends ChainableReaderFilter {
        /**
         * @param line the string to be trimmed
         * @return the trimmed string
         */
        public String filter(String line) {
            return line.trim();
        }
    }



    /** Filter remove empty tokens */
    public static class IgnoreBlank extends ChainableReaderFilter {
        /**
         * @param line the line to modify
         * @return the trimmed line
         */
        public String filter(String line) {
            if (line.trim().isEmpty()) {
                return null;
            }
            return line;
        }
    }

    /**
     * Filter to delete characters
     */
    public static class DeleteCharacters extends ProjectComponent
        implements Filter, ChainableReader {
        // Attributes
        /** the list of characters to remove from the input */
        private String deleteChars = "";

        /**
         * Set the list of characters to delete
         * @param deleteChars the list of characters
         */
        public void setChars(String deleteChars) {
            this.deleteChars = resolveBackSlash(deleteChars);
        }

        /**
         * remove characters from a string
         * @param string the string to remove the characters from
         * @return the converted string
         */
        public String filter(String string) {
            StringBuffer output = new StringBuffer(string.length());
            for (int i = 0; i < string.length(); ++i) {
                char ch = string.charAt(i);
                if (!(isDeleteCharacter(ch))) {
                    output.append(ch);
                }
            }
            return output.toString();
        }

        /**
         * factory method to provide a reader that removes
         * the characters from a reader as part of a filter
         * chain
         * @param reader the reader object
         * @return the chained reader object
         */
        public Reader chain(Reader reader) {
            return new BaseFilterReader(reader) {
                /**
                 * @return the next non delete character
                 */
                public int read()
                    throws IOException {
                    while (true) {
                        int c = in.read();
                        if (c == -1) {
                            return c;
                        }
                        if (!(isDeleteCharacter((char) c))) {
                            return c;
                        }
                    }
                }
            };
        }

        /**
         *  check if the character c is to be deleted
         *
         * @param c char to test
         * @return true if the supplied char is in the list to be stripped.
         */
        private boolean isDeleteCharacter(char c) {
            for (int d = 0; d < deleteChars.length(); ++d) {
                if (deleteChars.charAt(d) ==  c) {
                    return true;
                }
            }
            return false;
        }
    }

    // --------------------------------------------------------
    //  static utility methods - could be placed somewhere else
    // --------------------------------------------------------

    /**
     * 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 with " \n\r\t\f"
     * a trailing '\' will be ignored
     *
     * @param input raw string with possible embedded '\'s
     * @return converted string
     */
    public static String resolveBackSlash(String input) {
        return StringUtils.resolveBackSlash(input);
    }

    /**
     * convert regex option flag characters to regex options
     * <ul>
     *   <li>g -  Regexp.REPLACE_ALL</li>
     *   <li>i -  Regexp.MATCH_CASE_INSENSITIVE</li>
     *   <li>m -  Regexp.MATCH_MULTILINE</li>
     *   <li>s -  Regexp.MATCH_SINGLELINE</li>
     * </ul>
     * @param flags the string containing the flags
     * @return the Regexp option bits
     */
    public static int convertRegexOptions(String flags) {
        return RegexpUtil.asOptions(flags);
    }
}
