/*
 * Copyright 2017 HugeGraph Authors
 *
 * 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.
 */

package org.apache.hugegraph.config;

import org.apache.hugegraph.config.ConfigOption;
import org.apache.hugegraph.config.OptionHolder;

import static org.apache.hugegraph.config.OptionChecker.allowValues;
import static org.apache.hugegraph.config.OptionChecker.disallowEmpty;
import static org.apache.hugegraph.config.OptionChecker.rangeInt;

public class RpcOptions extends OptionHolder {

    private RpcOptions() {
        super();
    }

    private static volatile RpcOptions instance;

    public static synchronized RpcOptions instance() {
        if (instance == null) {
            instance = new RpcOptions();
            instance.registerOptions();
        }
        return instance;
    }

    public static final ConfigOption<String> RPC_SERVER_HOST =
            new ConfigOption<>(
                    "rpc.server_host",
                    "The hosts/ips bound by rpc server to provide services, " +
                    "empty value means not enabled.",
                    null,
                    ""
            );

    public static final ConfigOption<Integer> RPC_SERVER_PORT =
            new ConfigOption<>(
                    "rpc.server_port",
                    "The port bound by rpc server to provide services.",
                    rangeInt(0, Integer.MAX_VALUE),
                    8090
            );

    public static final ConfigOption<Boolean> RPC_ADAPTIVE_PORT =
            new ConfigOption<>(
                    "rpc.server_adaptive_port",
                    "Whether the bound port is adaptive, if it's enabled, " +
                    "when the port is in use, automatically +1 to detect " +
                    "the next available port. Note that this process is " +
                    "not atomic, so there may still be port conflicts.",
                    disallowEmpty(),
                    false
            );

    public static final ConfigOption<Integer> RPC_SERVER_TIMEOUT =
            new ConfigOption<>(
                    "rpc.server_timeout",
                    "The timeout(in seconds) of rpc server execution.",
                    rangeInt(1, Integer.MAX_VALUE),
                    30
            );

    public static final ConfigOption<String> RPC_REMOTE_URL =
            new ConfigOption<>(
                    "rpc.remote_url",
                    "The remote urls of rpc peers, it can be set to " +
                    "multiple addresses, which are concat by ',', " +
                    "empty value means not enabled.",
                    null,
                    ""
            );

    public static final ConfigOption<Integer> RPC_CLIENT_CONNECT_TIMEOUT =
            new ConfigOption<>(
                    "rpc.client_connect_timeout",
                    "The timeout(in seconds) of rpc client connect to rpc " +
                    "server.",
                    rangeInt(1, Integer.MAX_VALUE),
                    20
            );

    public static final ConfigOption<Integer> RPC_CLIENT_RECONNECT_PERIOD =
            new ConfigOption<>(
                    "rpc.client_reconnect_period",
                    "The period(in seconds) of rpc client reconnect to rpc " +
                    "server.",
                    rangeInt(1, Integer.MAX_VALUE),
                    10
            );

    public static final ConfigOption<Integer> RPC_CLIENT_READ_TIMEOUT =
            new ConfigOption<>(
                    "rpc.client_read_timeout",
                    "The timeout(in seconds) of rpc client read from rpc " +
                    "server.",
                    rangeInt(1, Integer.MAX_VALUE),
                    40
            );

    public static final ConfigOption<Integer> RPC_CLIENT_RETRIES =
            new ConfigOption<>(
                    "rpc.client_retries",
                    "Failed retry number of rpc client calls to rpc server.",
                    rangeInt(0, Integer.MAX_VALUE),
                    3
            );

    public static final ConfigOption<String> RPC_CLIENT_LOAD_BALANCER =
            new ConfigOption<>(
                    "rpc.client_load_balancer",
                    "The rpc client uses a load-balancing algorithm to " +
                    "access multiple rpc servers in one cluster. Default " +
                    "value is 'consistentHash', means forwording by request " +
                    "parameters.",
                    allowValues("random", "localPref", "roundRobin",
                                "consistentHash", "weightRoundRobin"),
                    "consistentHash"
            );

    public static final ConfigOption<String> RPC_PROTOCOL =
            new ConfigOption<>(
                    "rpc.protocol",
                    "Rpc communication protocol, client and server need to " +
                    "be specified the same value.",
                    allowValues("bolt", "rest", "dubbo", "h2c", "http"),
                    "bolt"
            );

    public static final ConfigOption<Integer> RPC_CONFIG_ORDER =
            new ConfigOption<>(
                    "rpc.config_order",
                    "Sofa rpc configuration file loading order, the larger " +
                    "the more later loading.",
                    rangeInt(1, Integer.MAX_VALUE),
                    999
            );

    public static final ConfigOption<String> RPC_LOGGER_IMPL =
            new ConfigOption<>(
                    "rpc.logger_impl",
                    "Sofa rpc log implementation class.",
                    disallowEmpty(),
                    "com.alipay.sofa.rpc.log.SLF4JLoggerImpl"
            );
}
