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 org.apache.cassandra.stress.Operation;
import org.apache.cassandra.stress.generate.DistributionFactory;
import org.apache.cassandra.stress.generate.PartitionGenerator;
import org.apache.cassandra.stress.generate.SeedManager;
import org.apache.cassandra.stress.operations.OpDistributionFactory;
import org.apache.cassandra.stress.operations.SampledOpDistributionFactory;
import org.apache.cassandra.stress.operations.predefined.PredefinedOperation;
import org.apache.cassandra.stress.report.Timer;
import org.apache.cassandra.stress.util.ResultLogger;

// Settings unique to the mixed command type
public class SettingsCommandPreDefinedMixed extends SettingsCommandPreDefined
{

    // Ratios for selecting commands - index for each Command, NaN indicates the command is not requested
    private final Map<Command, Double> ratios;
    private final DistributionFactory clustering;
    private final Options options;

    public SettingsCommandPreDefinedMixed(Options options)
    {
        super(Command.MIXED, options);

        clustering = options.clustering.get();
        ratios = options.probabilities.ratios();
        this.options = options;
        if (ratios.size() == 0)
            throw new IllegalArgumentException("Must specify at least one command with a non-zero ratio");
    }

    public OpDistributionFactory getFactory(final StressSettings settings)
    {
        final SeedManager seeds = new SeedManager(settings);
        return new SampledOpDistributionFactory<Command>(ratios, clustering)
        {
            protected List<? extends Operation> get(Timer timer, Command key, boolean isWarmup)
            {
                return Collections.singletonList(PredefinedOperation.operation(key, timer, SettingsCommandPreDefinedMixed.this.newGenerator(settings), seeds, settings, add));
            }
        };
    }

    // Option Declarations

    static class Options extends SettingsCommandPreDefined.Options
    {
        static List<OptionEnumProbabilities.Opt<Command>> probabilityOptions = new ArrayList<>();
        static
        {
            for (Command command : Command.values())
            {
                if (command.category == null)
                    continue;
                String defaultValue;
                switch (command)
                {
                    case MIXED:
                        continue;
                    case READ:
                    case WRITE:
                        defaultValue = "1";
                        break;
                    default:
                        defaultValue = null;
                }
                probabilityOptions.add(new OptionEnumProbabilities.Opt<>(command, defaultValue));
            }
        }

        protected Options(SettingsCommand.Options parent)
        {
            super(parent);
        }
        final OptionDistribution clustering = new OptionDistribution("clustering=", "GAUSSIAN(1..10)", "Distribution clustering runs of operations of the same kind");
        final OptionEnumProbabilities probabilities = new OptionEnumProbabilities<>(probabilityOptions, "ratio", "Specify the ratios for operations to perform; e.g. (read=2,write=1) will perform 2 reads for each write");

        @Override
        public List<? extends Option> options()
        {
            return merge(Arrays.asList(clustering, probabilities), super.options());
        }

    }

    public void printSettings(ResultLogger out)
    {
        super.printSettings(out);
        out.printf("  Command Ratios: %s%n", ratios);
        out.printf("  Command Clustering Distribution: %s%n", options.clustering.getOptionAsString());
    }

    // CLI utility methods

    public static SettingsCommandPreDefinedMixed build(String[] params)
    {
        GroupedOptions options = GroupedOptions.select(params,
                new Options(new SettingsCommand.Uncertainty()),
                new Options(new SettingsCommand.Count()),
                new Options(new SettingsCommand.Duration()));
        if (options == null)
        {
            printHelp();
            System.out.println("Invalid MIXED options provided, see output for valid options");
            System.exit(1);
        }
        return new SettingsCommandPreDefinedMixed((Options) options);
    }

    public static void printHelp()
    {
        GroupedOptions.printOptions(System.out, "mixed",
                                    new Options(new SettingsCommand.Uncertainty()),
                                    new Options(new SettingsCommand.Count()),
                                    new Options(new SettingsCommand.Duration()));
    }

    public static Runnable helpPrinter()
    {
        return new Runnable()
        {
            @Override
            public void run()
            {
                printHelp();
            }
        };
    }
}
