/*
 * 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.ignite.internal.commandline;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.logging.Logger;
import org.apache.ignite.internal.client.GridClient;
import org.apache.ignite.internal.client.GridClientConfiguration;
import org.apache.ignite.internal.client.GridClientNode;
import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
import org.apache.ignite.internal.commandline.cache.argument.TracingConfigurationCommandArg;
import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationArguments;
import org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand;
import org.apache.ignite.spi.tracing.Scope;
import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTask;
import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskArg;
import org.apache.ignite.internal.visor.tracing.configuration.VisorTracingConfigurationTaskResult;

import static org.apache.ignite.IgniteSystemProperties.IGNITE_ENABLE_EXPERIMENTAL_COMMAND;
import static org.apache.ignite.internal.commandline.CommandHandler.UTILITY_NAME;
import static org.apache.ignite.internal.commandline.CommandList.TRACING_CONFIGURATION;
import static org.apache.ignite.internal.commandline.CommandLogger.grouped;
import static org.apache.ignite.internal.commandline.CommandLogger.join;
import static org.apache.ignite.internal.commandline.CommandLogger.optional;
import static org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.GET_ALL;
import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.RESET_ALL;
import static org.apache.ignite.internal.commandline.tracing.configuration.TracingConfigurationSubcommand.of;
import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_ALWAYS;
import static org.apache.ignite.spi.tracing.TracingConfigurationParameters.SAMPLING_RATE_NEVER;

/**
 * Commands associated with tracing configuration functionality.
 */
public class TracingConfigurationCommand implements Command<TracingConfigurationArguments> {
    /** Arguments. */
    private TracingConfigurationArguments args;

    /** {@inheritDoc} */
    @Override public void printUsage(Logger log) {
        if (!experimentalEnabled())
            return;

        Command.usage(
            log,
            "Print tracing configuration: ",
            TRACING_CONFIGURATION);

        Command.usage(
            log,
            "Print tracing configuration: ",
            TRACING_CONFIGURATION,
            TracingConfigurationSubcommand.GET_ALL.text(),
            optional(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())));

        Command.usage(
            log,
            "Print specific tracing configuration based on specified " +
                TracingConfigurationCommandArg.SCOPE.argName() + " and " +
                TracingConfigurationCommandArg.LABEL.argName() + ": ",
            TRACING_CONFIGURATION,
            TracingConfigurationSubcommand.GET.text(),
            grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())),
            optional(TracingConfigurationCommandArg.LABEL.argName()));

        Command.usage(
            log,
            "Reset all specific tracing configuration the to default. If " +
                TracingConfigurationCommandArg.SCOPE.argName() +
                " is specified, then remove all label specific configuration for the given scope and reset given scope" +
                " specific configuration to the default, if " + TracingConfigurationCommandArg.SCOPE.argName() +
                " is skipped then reset all tracing configurations to the default. Print tracing configuration.",
            TRACING_CONFIGURATION,
            RESET_ALL.text(),
            optional(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())));

        Command.usage(
            log,
            "Reset specific tracing configuration to the default. If both " +
                TracingConfigurationCommandArg.SCOPE.argName() + " and " +
                TracingConfigurationCommandArg.LABEL.argName() + " are specified then remove given configuration," +
                " if only " + TracingConfigurationCommandArg.SCOPE.argName() +
                " is specified then reset given configuration to the default." +
                " Print reseted configuration.",
            TRACING_CONFIGURATION,
            TracingConfigurationSubcommand.RESET.text(),
            grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values())),
            optional(TracingConfigurationCommandArg.LABEL.argName()));

        Command.usage(
            log,
            "Set new tracing configuration. If both " +
                TracingConfigurationCommandArg.SCOPE.argName() + " and " +
                TracingConfigurationCommandArg.LABEL.argName() + " are specified then add or override label" +
                " specific configuration, if only " + TracingConfigurationCommandArg.SCOPE.argName() +
                " is specified, then override scope specific configuration. Print applied configuration.",
            TRACING_CONFIGURATION,
            TracingConfigurationSubcommand.SET.text(),
            grouped(TracingConfigurationCommandArg.SCOPE.argName(), join("|", Scope.values()),
            optional(TracingConfigurationCommandArg.LABEL.argName()),
            optional(TracingConfigurationCommandArg.SAMPLING_RATE.argName(),
                "Decimal value between 0 and 1, " +
                "where 0 means never and 1 means always. " +
                "More or less reflects the probability of sampling specific trace."),
            optional(TracingConfigurationCommandArg.INCLUDED_SCOPES.argName(),
                "Set of scopes with comma as separator ",
                join("|", Scope.values()))));
    }

    /**
     * Execute tracing-configuration command.
     *
     * @param clientCfg Client configuration.
     * @throws Exception If failed to execute tracing-configuration action.
     */
    @Override public Object execute(GridClientConfiguration clientCfg, Logger log) throws Exception {
        if (experimentalEnabled()) {
            try (GridClient client = Command.startClient(clientCfg)) {
                UUID crdId = client.compute()
                    //Only non client node can be coordinator.
                    .nodes(node -> !node.isClient())
                    .stream()
                    .min(Comparator.comparingLong(GridClientNode::order))
                    .map(GridClientNode::nodeId)
                    .orElse(null);

                VisorTracingConfigurationTaskResult res = executeTaskByNameOnNode(
                    client,
                    VisorTracingConfigurationTask.class.getName(),
                    toVisorArguments(args),
                    crdId,
                    clientCfg
                );

                printResult(res, log::info);

                return res;
            }
            catch (Throwable e) {
                log.severe("Failed to execute tracing-configuration command='" + args.command().text() + "'");

                throw e;
            }
        } else {
            log.warning(String.format("For use experimental command add %s=true to JVM_OPTS in %s",
                IGNITE_ENABLE_EXPERIMENTAL_COMMAND, UTILITY_NAME));

            return null;
        }
    }

    /** {@inheritDoc} */
    @Override public void parseArguments(CommandArgIterator argIter) {
        // If there is no arguments, use list command.
        if (!argIter.hasNextSubArg()) {
            args = new TracingConfigurationArguments.Builder(TracingConfigurationSubcommand.GET_ALL).build();

            return;
        }

        TracingConfigurationSubcommand cmd = of(argIter.nextArg("Expected tracing configuration action."));

        if (cmd == null)
            throw new IllegalArgumentException("Expected correct tracing configuration action.");

        TracingConfigurationArguments.Builder tracingConfigurationArgs = new TracingConfigurationArguments.Builder(cmd);

        Scope scope = null;

        String lb = null;

        double samplingRate = SAMPLING_RATE_NEVER;

        Set<Scope> includedScopes = new HashSet<>();

        while (argIter.hasNextSubArg()) {
            TracingConfigurationCommandArg arg =
                CommandArgUtils.of(argIter.nextArg(""), TracingConfigurationCommandArg.class);

            String strVal;

            assert arg != null;

            switch (arg) {
                case SCOPE: {
                    String peekedNextArg = argIter.peekNextArg();

                    if (!TracingConfigurationCommandArg.args().contains(peekedNextArg)) {
                        strVal = argIter.nextArg(
                            "The scope should be specified. The following " +
                                "values can be used: " + Arrays.toString(Scope.values()) + '.');

                        try {
                            scope = Scope.valueOf(strVal);
                        }
                        catch (IllegalArgumentException e) {
                            throw new IllegalArgumentException(
                                "Invalid scope '" + strVal + "'. The following " +
                                    "values can be used: " + Arrays.toString(Scope.values()) + '.');
                        }
                    }

                    break;
                }
                case LABEL: {
                    lb = argIter.nextArg(
                        "The label should be specified.");

                    break;
                }
                case SAMPLING_RATE: {
                    strVal = argIter.nextArg(
                        "The sampling rate should be specified. Decimal value between 0 and 1 should be used.");

                    try {
                        samplingRate = Double.parseDouble(strVal);
                    }
                    catch (IllegalArgumentException e) {
                        throw new IllegalArgumentException(
                            "Invalid sampling-rate '" + strVal + "'. Decimal value between 0 and 1 should be used.");
                    }

                    if (samplingRate < SAMPLING_RATE_NEVER || samplingRate > SAMPLING_RATE_ALWAYS)
                        throw new IllegalArgumentException(
                            "Invalid sampling-rate '" + strVal + "'. Decimal value between 0 and 1 should be used.");

                    break;
                }
                case INCLUDED_SCOPES: {
                    Set<String> setStrVals = argIter.nextStringSet(
                        "At least one supported scope should be specified.");

                    for (String scopeStrVal : setStrVals) {
                        try {
                            includedScopes.add(Scope.valueOf(scopeStrVal));
                        }
                        catch (IllegalArgumentException e) {
                            throw new IllegalArgumentException(
                                "Invalid supported scope '" + scopeStrVal + "'. The following " +
                                    "values can be used: " + Arrays.toString(Scope.values()) + '.');
                        }
                    }

                    break;
                }
            }
        }

        // Scope is a mandatory attribute for all sub-commands except get_all and reset_all.
        if ((cmd != GET_ALL && cmd != RESET_ALL) && scope == null) {
            throw new IllegalArgumentException(
                "Scope attribute is missing. Following values can be used: " + Arrays.toString(Scope.values()) + '.');
        }

        switch (cmd) {
            case GET_ALL:
            case RESET_ALL: {
                tracingConfigurationArgs.withScope(scope);

                break;
            }

            case RESET:
            case GET: {
                tracingConfigurationArgs.withScope(scope).withLabel(lb);

                break;
            }

            case SET: {
                tracingConfigurationArgs.withScope(scope).withLabel(lb).withSamplingRate(samplingRate).
                    withIncludedScopes(includedScopes);

                break;
            }

            default: {
                // We should never get here.
                assert false : "Unexpected tracing configuration argument [arg= " + cmd + ']';
            }
        }

        args = tracingConfigurationArgs.build();
    }

    /** {@inheritDoc} */
    @Override public TracingConfigurationArguments arg() {
        return args;
    }

    /** {@inheritDoc} */
    @Override public String name() {
        return TRACING_CONFIGURATION.toCommandName();
    }

    /** {@inheritDoc} */
    @Override public boolean experimental() {
        return true;
    }

    /**
     * Print result.
     *
     * @param res Visor tracing configuration result.
     * @param printer Printer.
     */
    private void printResult(VisorTracingConfigurationTaskResult res, Consumer<String> printer) {
        res.print(printer);
    }

    /**
     * Prepare task argument.
     *
     * @param args Argument from command line.
     * @return Task argument.
     */
    private VisorTracingConfigurationTaskArg toVisorArguments(TracingConfigurationArguments args) {
        return new VisorTracingConfigurationTaskArg(
            args.command().visorBaselineOperation(),
            args.scope(),
            args.label(),
            args.samplingRate(),
            args.includedScopes()
        );
    }
}
