/*
 * Copyright 2019-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.net.optical.cli;

import com.google.common.collect.ImmutableMap;
import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Completion;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cli.net.OpticalConnectPointCompleter;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.GridType;
import org.onosproject.net.OchSignal;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.Device;
import org.onosproject.net.flow.instructions.Instructions;

import java.util.Map;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Enable the optical channel and tune the wavelength via a flow rule based on a given Signal.
 */
@Service
@Command(scope = "onos", name = "port-wavelength",
        description = "Enable the optical channel and tune the wavelength via a flow rule ")
public class PortWaveLengthCommand extends AbstractShellCommand {

    private static final String SIGNAL_FORMAT = "slotGranularity/channelSpacing(in GHz e.g 6.25,12.5,25,50,100)/" +
            "spaceMultiplier/gridType(cwdm, flex, dwdm) " + "e.g 1/6.25/1/flex";

    private static final String CH_6P25 = "6.25";
    private static final String CH_12P5 = "12.5";
    private static final String CH_25 = "25";
    private static final String CH_50 = "50";
    private static final String CH_100 = "100";

    private static final Map<String, ChannelSpacing> CHANNEL_SPACING_MAP = ImmutableMap
            .<String, ChannelSpacing>builder()
            .put(CH_6P25, ChannelSpacing.CHL_6P25GHZ)
            .put(CH_12P5, ChannelSpacing.CHL_12P5GHZ)
            .put(CH_25, ChannelSpacing.CHL_25GHZ)
            .put(CH_50, ChannelSpacing.CHL_50GHZ)
            .put(CH_100, ChannelSpacing.CHL_100GHZ)
            .build();

    @Argument(index = 0, name = "connectPoint",
            description = "Device/Port Description",
            required = true, multiValued = false)
    @Completion(OpticalConnectPointCompleter.class)
    String connectPointString = "";


    @Argument(index = 1, name = "signal",
            description = "Optical Signal. Format = " + SIGNAL_FORMAT,
            required = true, multiValued = false)
    String signal = "";

    private OchSignal createOchSignal() throws IllegalArgumentException {
        if (signal == null) {
            return null;
        }
        try {
            String[] splitted = signal.split("/");
            checkArgument(splitted.length == 4,
                    "signal requires 4 parameters: " + SIGNAL_FORMAT);
            int slotGranularity = Integer.parseInt(splitted[0]);
            String chSpacing = splitted[1];
            ChannelSpacing channelSpacing = checkNotNull(CHANNEL_SPACING_MAP.get(chSpacing),
                    String.format("invalid channel spacing: %s", chSpacing));
            int multiplier = Integer.parseInt(splitted[2]);
            String gdType = splitted[3].toUpperCase();
            GridType gridType = GridType.valueOf(gdType);
            return new OchSignal(gridType, channelSpacing, multiplier, slotGranularity);
        } catch (RuntimeException e) {
            /* catching RuntimeException as both NullPointerException (thrown by
             * checkNotNull) and IllegalArgumentException (thrown by checkArgument)
             * are subclasses of RuntimeException.
             */
            String msg = String.format("Invalid signal format: %s, expected format is %s.",
                    signal, SIGNAL_FORMAT);
            print(msg);
            throw new IllegalArgumentException(msg, e);
        }
    }


    @Override
    protected void doExecute() throws Exception {
        FlowRuleService flowService = get(FlowRuleService.class);
        DeviceService deviceService = get(DeviceService.class);
        CoreService coreService = get(CoreService.class);
        ConnectPoint cp = ConnectPoint.deviceConnectPoint(connectPointString);

        TrafficSelector.Builder trafficSelectorBuilder = DefaultTrafficSelector.builder();
        TrafficTreatment.Builder trafficTreatmentBuilder = DefaultTrafficTreatment.builder();
        FlowRule.Builder flowRuleBuilder = DefaultFlowRule.builder();


        // an empty traffic selector
        TrafficSelector trafficSelector = trafficSelectorBuilder.matchInPort(cp.port()).build();
        OchSignal ochSignal = createOchSignal();

        TrafficTreatment trafficTreatment = trafficTreatmentBuilder
                .add(Instructions.modL0Lambda(ochSignal))
                .add(Instructions.createOutput(deviceService.getPort(cp).number()))
                .build();

        Device device = deviceService.getDevice(cp.deviceId());
        int priority = 100;
        ApplicationId appId = coreService.registerApplication("org.onosproject.optical-model");
        log.info(appId.name());
        FlowRule addFlow = flowRuleBuilder
                .withPriority(priority)
                .fromApp(appId)
                .withTreatment(trafficTreatment)
                .withSelector(trafficSelector)
                .forDevice(device.id())
                .makePermanent()
                .build();
        flowService.applyFlowRules(addFlow);

    }
}
