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.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.base.Function;

import org.apache.cassandra.stress.generate.DistributionFactory;
import org.apache.cassandra.stress.generate.RatioDistribution;
import org.apache.cassandra.stress.generate.RatioDistributionFactory;

/**
 * For selecting a mathematical distribution
 */
public class OptionRatioDistribution extends Option
{

    public static final Function<String, RatioDistributionFactory> BUILDER = new Function<String, RatioDistributionFactory>()
    {
        public RatioDistributionFactory apply(String s)
        {
            return get(s);
        }
    };

    private static final Pattern FULL = Pattern.compile("(.*)/([0-9]+[KMB]?)", Pattern.CASE_INSENSITIVE);

    final OptionDistribution delegate;
    private double divisor;
    final String defaultSpec;

    public OptionRatioDistribution(String prefix, String defaultSpec, String description)
    {
        this(prefix, defaultSpec, description, defaultSpec != null);
    }

    public OptionRatioDistribution(String prefix, String defaultSpec, String description, boolean required)
    {
        delegate = new OptionDistribution(prefix, null, description, required);
        this.defaultSpec = defaultSpec;
    }

    @Override
    public boolean accept(String param)
    {
        Matcher m = FULL.matcher(param);
        if (!m.matches() || !delegate.accept(m.group(1)))
            return false;
        divisor = OptionDistribution.parseLong(m.group(2));
        return true;
    }

    public static RatioDistributionFactory get(String spec)
    {
        OptionRatioDistribution opt = new OptionRatioDistribution("", "", "", true);
        if (!opt.accept(spec))
            throw new IllegalArgumentException("Invalid ratio definition: "+spec);
        return opt.get();
    }

    public RatioDistributionFactory get()
    {
        if (delegate.setByUser())
            return new DelegateFactory(delegate.get(), divisor);
        if (defaultSpec == null)
            return null;
        OptionRatioDistribution sub = new OptionRatioDistribution("", null, null, true);
        if (!sub.accept(defaultSpec))
            throw new IllegalStateException("Invalid default spec: " + defaultSpec);
        return sub.get();
    }

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

    public String longDisplay()
    {
        return delegate.longDisplay();
    }

    @Override
    public List<String> multiLineDisplay()
    {
        return Arrays.asList(
                GroupedOptions.formatMultiLine("EXP(min..max)/divisor", "An exponential ratio distribution over the range [min..max]/divisor"),
                GroupedOptions.formatMultiLine("EXTREME(min..max,shape)/divisor", "An extreme value (Weibull) ratio distribution over the range [min..max]/divisor"),
                GroupedOptions.formatMultiLine("GAUSSIAN(min..max,stdvrng)/divisor", "A gaussian/normal ratio distribution, where mean=(min+max)/2, and stdev is ((mean-min)/stdvrng)/divisor"),
                GroupedOptions.formatMultiLine("GAUSSIAN(min..max,mean,stdev)/divisor", "A gaussian/normal ratio distribution, with explicitly defined mean and stdev"),
                GroupedOptions.formatMultiLine("UNIFORM(min..max)/divisor", "A uniform ratio distribution over the range [min, max]/divisor"),
                GroupedOptions.formatMultiLine("FIXED(val)/divisor", "A fixed ratio distribution, always returning the same value"),
                "Preceding the name with ~ will invert the distribution, e.g. ~exp(1..10)/10 will yield 0.1 least, instead of most, often",
                "Aliases: extr, gauss, normal, norm, weibull"
        );
    }

    boolean setByUser()
    {
        return delegate.setByUser();
    }

    boolean present()
    {
        return delegate.present();
    }

    @Override
    public String shortDisplay()
    {
        return delegate.shortDisplay();
    }
    public String getOptionAsString()
    {
        return delegate.getOptionAsString();
    }


    // factories

    private static final class DelegateFactory implements RatioDistributionFactory
    {
        final DistributionFactory delegate;
        final double divisor;

        private DelegateFactory(DistributionFactory delegate, double divisor)
        {
            this.delegate = delegate;
            this.divisor = divisor;
        }

        @Override
        public RatioDistribution get()
        {
            return new RatioDistribution(delegate.get(), divisor);
        }

        @Override
        public String getConfigAsString(){return String.format("Ratio: divisor=%f;delegate=%s",divisor, delegate.getConfigAsString());};

    }

    @Override
    public int hashCode()
    {
        return delegate.hashCode();
    }

    @Override
    public boolean equals(Object that)
    {
        return super.equals(that) && ((OptionRatioDistribution) that).delegate.equals(this.delegate);
    }

}
