// 
// Decompiled by Procyon v0.6.0
// 

package org.jline.reader.impl.completer;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import org.jline.reader.Candidate;
import org.jline.reader.ParsedLine;
import org.jline.reader.LineReader;
import java.util.Arrays;
import java.util.Objects;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jline.reader.Completer;

public class ArgumentCompleter implements Completer
{
    private final List<Completer> completers;
    private boolean strict;
    private boolean strictCommand;
    
    public ArgumentCompleter(final Collection<Completer> completers) {
        this.completers = new ArrayList<Completer>();
        this.strict = true;
        this.strictCommand = true;
        Objects.requireNonNull(completers);
        this.completers.addAll(completers);
    }
    
    public ArgumentCompleter(final Completer... completers) {
        this(Arrays.asList(completers));
    }
    
    public void setStrict(final boolean strict) {
        this.strict = strict;
    }
    
    public void setStrictCommand(final boolean strictCommand) {
        this.strictCommand = strictCommand;
    }
    
    public boolean isStrict() {
        return this.strict;
    }
    
    public List<Completer> getCompleters() {
        return this.completers;
    }
    
    @Override
    public void complete(final LineReader reader, final ParsedLine line, final List<Candidate> candidates) {
        Objects.requireNonNull(line);
        Objects.requireNonNull(candidates);
        if (line.wordIndex() < 0) {
            return;
        }
        final List<Completer> completers = this.getCompleters();
        Completer completer;
        if (line.wordIndex() >= completers.size()) {
            completer = completers.get(completers.size() - 1);
        }
        else {
            completer = completers.get(line.wordIndex());
        }
        for (int i = this.strictCommand ? 0 : 1; this.isStrict() && i < line.wordIndex(); ++i) {
            final int idx = (i >= completers.size()) ? (completers.size() - 1) : i;
            if (idx != 0 || this.strictCommand) {
                final Completer sub = completers.get(idx);
                final List<? extends CharSequence> args = line.words();
                final String arg = (args == null || i >= args.size()) ? "" : ((CharSequence)args.get(i)).toString();
                final List<Candidate> subCandidates = new LinkedList<Candidate>();
                sub.complete(reader, new ArgumentLine(arg, arg.length()), subCandidates);
                boolean found = false;
                for (final Candidate cand : subCandidates) {
                    if (cand.value().equals(arg)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    return;
                }
            }
        }
        completer.complete(reader, line, candidates);
    }
    
    public static class ArgumentLine implements ParsedLine
    {
        private final String word;
        private final int cursor;
        
        public ArgumentLine(final String word, final int cursor) {
            this.word = word;
            this.cursor = cursor;
        }
        
        @Override
        public String word() {
            return this.word;
        }
        
        @Override
        public int wordCursor() {
            return this.cursor;
        }
        
        @Override
        public int wordIndex() {
            return 0;
        }
        
        @Override
        public List<String> words() {
            return Collections.singletonList(this.word);
        }
        
        @Override
        public String line() {
            return this.word;
        }
        
        @Override
        public int cursor() {
            return this.cursor;
        }
    }
}
