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.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class SettingsPort implements Serializable
{

    public final int nativePort;
    public final int thriftPort;
    public final int jmxPort;

    public SettingsPort(PortOptions options)
    {
        nativePort = Integer.parseInt(options.nativePort.value());
        thriftPort = Integer.parseInt(options.thriftPort.value());
        jmxPort = Integer.parseInt(options.jmxPort.value());
    }

    // Option Declarations

    private static final class PortOptions extends GroupedOptions
    {
        final OptionSimple nativePort = new OptionSimple("native=", "[0-9]+", "9042", "Use this port for the Cassandra native protocol", false);
        final OptionSimple thriftPort = new OptionSimple("thrift=", "[0-9]+", "9160", "Use this port for the thrift protocol", false);
        final OptionSimple jmxPort = new OptionSimple("jmx=", "[0-9]+", "7199", "Use this port for retrieving statistics over jmx", false);

        @Override
        public List<? extends Option> options()
        {
            return Arrays.asList(nativePort, thriftPort, jmxPort);
        }
    }

    // CLI Utility Methods

    public static SettingsPort get(Map<String, String[]> clArgs)
    {
        String[] params = clArgs.remove("-port");
        if (params == null)
        {
            return new SettingsPort(new PortOptions());
        }
        PortOptions options = GroupedOptions.select(params, new PortOptions());
        if (options == null)
        {
            printHelp();
            System.out.println("Invalid -port options provided, see output for valid options");
            System.exit(1);
        }
        return new SettingsPort(options);
    }

    public static void printHelp()
    {
        GroupedOptions.printOptions(System.out, "-port", new PortOptions());
    }

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

