/*
 * 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.felix.gogo.shell;

import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class History {

    private static final int SIZE_DEFAULT = 100;

    private LinkedList<String> commands;

    private int limit;

    public History() {
        this.limit = SIZE_DEFAULT;
        this.commands = new LinkedList<>();
    }

    CharSequence evaluate(final CharSequence commandLine) {

        /*
         * <pre>
         * hist = ( '!' spec ) | ( '^' subst ) .
         * spec = '!' ( '!' | idx | '?' find | string ) [ ':' [ 'a' | 'g' ] 's' regex ] . idx = [ '-' ] { 0..9 } .
         * find = string ( '?' | EOL ) .
         * subst = pat '^' repl '^' EOL .
         * regex = str pat str repl str EOL .
         * </pre>
         */

        final CharacterIterator ci = new StringCharacterIterator(commandLine.toString());

        String event;
        char c = ci.current();
        if (c == '!') {
            c = ci.next();
            if (c == '!') {
                event = this.commands.getLast();
                ci.next();
            } else if ((c >= '0' && c <= '9') || c == '-') {
                event = getCommand(ci);
            } else if (c == '?') {
                event = findContains(ci);
                ci.next();
            } else {
                ci.previous();
                event = findStartsWith(ci);
            }
        } else if (c == '^') {
            event = subst(ci, c, false, this.commands.getLast());
        } else {
            throw new IllegalArgumentException(commandLine + ": Unsupported event");
        }

        if (ci.current() == ':') {
            c = ci.next();
            boolean global = (c == 'a' || c == 'g');
            if (global) {
                c = ci.next();
            }
            if (c == 's') {
                event = subst(ci, ci.next(), global, event);
            }
        }

        return event;
    }

    /**
     * Returns the command history, oldest command first
     */
    Iterator<String> getHistory() {
        return this.commands.iterator();
    }

    void append(final CharSequence commandLine) {
        commands.add(commandLine.toString());
        if (commands.size() > this.limit) {
            commands.removeFirst();
        }
    }

    private String getCommand(final CharacterIterator ci) {
        final StringBuilder s = new StringBuilder();
        char c = ci.current();
        do {
            s.append(c);
            c = ci.next();
        } while (c >= '0' && c <= '9');
        final int n = Integer.parseInt(s.toString());
        final int pos = ((n < 0) ? this.commands.size() : -1) + n;
        if (pos >= 0 && pos < this.commands.size()) {
            return this.commands.get(pos);
        }
        throw new IllegalArgumentException("!" + n + ": event not found");
    }

    private String findContains(final CharacterIterator ci) {
        CharSequence part = findDelimiter(ci, '?');
        final ListIterator<String> iter = this.commands.listIterator(this.commands.size());
        while (iter.hasPrevious()) {
            String value = iter.previous();
            if (value.contains(part)) {
                return value;
            }
        }

        throw new IllegalArgumentException("No command containing '" + part + "' in the history");
    }

    private String findStartsWith(final CharacterIterator ci) {
        String part = findDelimiter(ci, ':').toString();
        final ListIterator<String> iter2 = this.commands.listIterator(this.commands.size());
        while (iter2.hasPrevious()) {
            String value = iter2.previous();
            if (value.startsWith(part)) {
                return value;
            }
        }

        throw new IllegalArgumentException("No command containing '" + part + "' in the history");
    }

    private String subst(final CharacterIterator ci, final char delimiter, final boolean replaceAll, final String event) {
        final String pattern = findDelimiter(ci, delimiter).toString();
        final String repl = findDelimiter(ci, delimiter).toString();
        if (pattern.length() == 0) {
            throw new IllegalArgumentException(":s" + event + ": substitution failed");
        }
        final Pattern regex = Pattern.compile(pattern);
        final Matcher m = regex.matcher(event);
        final StringBuffer res = new StringBuffer();

        if (!m.find()) {
            throw new IllegalArgumentException(":s" + event + ": substitution failed");
        }
        do {
            m.appendReplacement(res, repl);
        } while (replaceAll && m.find());
        m.appendTail(res);
        return res.toString();
    }

    private CharSequence findDelimiter(final CharacterIterator ci, char delimiter) {
        final StringBuilder b = new StringBuilder();
        for (char c = ci.next(); c != CharacterIterator.DONE && c != delimiter; c = ci.next()) {
            if (c == '\\') {
                c = ci.next();
            }
            b.append(c);
        }
        return b;
    }
}
