package org.apache.cassandra.stress.settings;
/*
 * 
 * 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.
 * 
 */


import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * For specifying multiple grouped sub-options in the form: group(arg1=,arg2,arg3) etc.
 */
abstract class OptionMulti extends Option
{

    private static final Pattern ARGS = Pattern.compile("([^,]+)", Pattern.CASE_INSENSITIVE);

    private final class Delegate extends GroupedOptions
    {
        @Override
        public List<? extends Option> options()
        {
            if (collectAsMap == null)
                return OptionMulti.this.options();

            List<Option> options = new ArrayList<>(OptionMulti.this.options());
            options.add(collectAsMap);
            return options;
        }
    }

    protected abstract List<? extends Option> options();

    public Map<String, String> extraOptions()
    {
        return collectAsMap == null ? new HashMap<String, String>() : collectAsMap.options;
    }

    private final String name;
    private final Pattern pattern;
    private final String description;
    private final Delegate delegate = new Delegate();
    private final CollectAsMap collectAsMap;

    public OptionMulti(String name, String description, boolean collectExtraOptionsInMap)
    {
        this.name = name;
        pattern = Pattern.compile(name + "\\((.*)\\)", Pattern.CASE_INSENSITIVE);
        this.description = description;
        this.collectAsMap = collectExtraOptionsInMap ? new CollectAsMap() : null;
    }

    @Override
    public boolean accept(String param)
    {
        Matcher m = pattern.matcher(param);
        if (!m.matches())
            return false;
        m = ARGS.matcher(m.group(1));
        int last = -1;
        while (m.find())
        {
            if (m.start() != last + 1)
                throw new IllegalArgumentException("Invalid " + name + " specification: " + param);
            last = m.end();
            if (!delegate.accept(m.group()))
            {

                throw new IllegalArgumentException("Invalid " + name + " specification: " + m.group());
            }
        }
        return true;
    }

    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(name);
        sb.append("(");
        for (Option option : delegate.options())
        {
            sb.append(option);
            sb.append(",");
        }
        sb.append(")");
        return sb.toString();
    }

    @Override
    public String shortDisplay()
    {
        return (happy() ? "[" : "") + name + "(?)" + (happy() ? "]" : "");
    }

    @Override
    public String longDisplay()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(name);
        sb.append("(");
        for (Option opt : delegate.options())
        {
            sb.append(opt.shortDisplay());
        }
        sb.append("): ");
        sb.append(description);
        return sb.toString();
    }

    @Override
    public List<String> multiLineDisplay()
    {
        final List<String> r = new ArrayList<>();
        for (Option option : options())
            r.add(option.longDisplay());
        return r;
    }

    @Override
    boolean happy()
    {
        return delegate.happy();
    }

    private static final class CollectAsMap extends Option
    {

        static final String description = "Extra options";
        Map<String, String> options = new LinkedHashMap<>();

        boolean accept(String param)
        {
            String[] args = param.split("=");
            if (args.length == 2 && args[1].length() > 0 && args[0].length() > 0)
            {
                if (options.put(args[0], args[1]) != null)
                    throw new IllegalArgumentException(args[0] + " set twice");
                return true;
            }
            return false;
        }

        boolean happy()
        {
            return true;
        }

        String shortDisplay()
        {
            return "[<option 1..N>=?]";
        }

        String longDisplay()
        {
            return GroupedOptions.formatLong(shortDisplay(), description);
        }

        List<String> multiLineDisplay()
        {
            return Collections.emptyList();
        }

        boolean setByUser()
        {
            return !options.isEmpty();
        }

        boolean present()
        {
            return !options.isEmpty();
        }
    }

    List<Option> optionsSetByUser()
    {
        List<Option> r = new ArrayList<>();
        for (Option option : delegate.options())
            if (option.setByUser())
                r.add(option);
        return r;
    }

    List<Option> defaultOptions()
    {
        List<Option> r = new ArrayList<>();
        for (Option option : delegate.options())
            if (!option.setByUser() && option.present())
                r.add(option);
        return r;
    }

    boolean setByUser()
    {
        for (Option option : delegate.options())
            if (option.setByUser())
                return true;
        return false;
    }

    boolean present()
    {
        for (Option option : delegate.options())
            if (option.present())
                return true;
        return false;
    }

}
