/*
 * Copyright 2017-present Open Networking Foundation
 *
 * Licensed 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.onosproject.imr.cli;

import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.core.DefaultApplicationId;
import org.onosproject.imr.IntentMonitorAndRerouteService;
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.Key;

/**
 * Starts monitoring of an intent submitting its key to the IMR service.
 */
@Command(scope = "imr", name = "startmon",
        description = "Submit an intent to the IMR application to start monitoring")
public class StartMonitorCommand extends AbstractShellCommand {

    @Option(name = "-l", aliases = "--longkey", description = "Treat intentKey as LongKey",
            required = false, multiValued = false)
    private boolean treatAsLongKey = false;

    @Argument(index = 0, name = "applicationId",
            description = "Application ID that submitted the intent",
            required = true)
    private Short appId;

    @Argument(index = 1, name = "applicationName",
            description = "Application Name that submitted the intent",
            required = true)
    private String appName;

    @Argument(index = 2, name = "intentKey",
            description = "String representation of the key of the intent",
            required = false)
    private String key;

    private IntentMonitorAndRerouteService imrService;
    private IntentService intentService;

    @Override
    protected void execute() {
        imrService = get(IntentMonitorAndRerouteService.class);
        intentService = get(IntentService.class);

        if (appId != null && appName != null) {
            if (key != null) {
                /*
                Intent key might be a StringKey or a LongKey, but in any case is
                provided via CLI as a string. To solve only ambiguity we check if
                "--longkey" CLI parameter has been set.
                 */
                if (treatAsLongKey) {
                    try {
                        Key intentKeyLong = Key.of(Integer.decode(key), new DefaultApplicationId(appId, appName));
                        for (Intent intent : intentService.getIntents()) {
                            if (intent.key().equals(intentKeyLong)) {
                                imrService.startMonitorIntent(intentKeyLong);
                                print("Started monitoring of intent with LongKey %s", intentKeyLong);
                                return;
                            }
                        }
                        imrService.startMonitorIntent(intentKeyLong);
                        print("Started monitoring of intent with LongKey %s, even if not yet submitted", intentKeyLong);
                    } catch (NumberFormatException nfe) {
                        print("\"%s\" is not a valid LongKey", key);
                    }
                } else {
                    Key intentKeyString = Key.of(key, new DefaultApplicationId(appId, appName));
                    for (Intent intent : intentService.getIntents()) {
                        if (intent.key().equals(intentKeyString)) {
                            imrService.startMonitorIntent(intentKeyString);
                            print("Started monitoring of intent with StringKey %s", intentKeyString);
                            return;
                        }
                    }
                    imrService.startMonitorIntent(intentKeyString);
                    print("Started monitoring of intent with StringKey %s, even if not yet submitted", intentKeyString);
                }
            } else {
                intentService.getIntents().forEach(i -> {
                    if (i.appId().equals(new DefaultApplicationId(appId, appName))) {
                        imrService.startMonitorIntent(i.key());
                        print("Started monitoring of intent with Key %s", i.key());
                    }
                });
            }
        }
    }
}
