/*
 * 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.segmentrouting.cli;


import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.ConnectPoint;
import org.onosproject.segmentrouting.SegmentRoutingService;
import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
import org.onosproject.segmentrouting.pwaas.L2Tunnel;
import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;

import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;


/**
 * Command to add a pseuwodire.
 */
@Command(scope = "onos", name = "pseudowire-add",
        description = "Add a pseudowire to the network configuration, if it already exists update it.")
public class PseudowireAddCommand extends AbstractShellCommand {

    @Argument(index = 0, name = "pwId",
            description = "Pseudowire ID",
            required = true, multiValued = false)
    String pwId;

    @Argument(index = 1, name = "pwLabel",
            description = "Pseudowire Label",
            required = true, multiValued = false)
    String pwLabel;

    @Argument(index = 2, name = "mode",
            description = "Mode used for pseudowire",
            required = true, multiValued = false)
    String mode;

    @Argument(index = 3, name = "sDTag",
            description = "Service delimiting tag",
            required = true, multiValued = false)
    String sDTag;

    @Argument(index = 4, name = "cP1",
            description = "Connection Point 1",
            required = true, multiValued = false)
    String cP1;

    @Argument(index = 5, name = "cP1InnerVlan",
            description = "Inner Vlan of Connection Point 1",
            required = true, multiValued = false)
    String cP1InnerVlan;

    @Argument(index = 6, name = "cP1OuterVlan",
            description = "Outer Vlan of Connection Point 1",
            required = true, multiValued = false)
    String cP1OuterVlan;

    @Argument(index = 7, name = "cP2",
            description = "Connection Point 2",
            required = true, multiValued = false)
    String cP2;

    @Argument(index = 8, name = "cP2InnerVlan",
            description = "Inner Vlan of Connection Point 2",
            required = true, multiValued = false)
    String cP2InnerVlan;

    @Argument(index = 9, name = "cP2OuterVlan",
            description = "Outer Vlan of Connection Point 2",
            required = true, multiValued = false)
    String cP2OuterVlan;

    @Override
    protected void execute() {

        SegmentRoutingService srService =
                AbstractShellCommand.get(SegmentRoutingService.class);

        L2Tunnel tun;
        L2TunnelPolicy policy;

        try {
            tun = new DefaultL2Tunnel(parseMode(mode), parseVlan(sDTag), parsePwId(pwId), parsePWLabel(pwLabel));
        } catch (Exception e) {
            print("Exception while parsing L2Tunnel : {}", e);
            return;
        }

        try {
            policy = new DefaultL2TunnelPolicy(parsePwId(pwId),
                                               ConnectPoint.deviceConnectPoint(cP1), parseVlan(cP1InnerVlan),
                                               parseVlan(cP1OuterVlan), ConnectPoint.deviceConnectPoint(cP2),
                                               parseVlan(cP2InnerVlan), parseVlan(cP2OuterVlan));

        } catch (Exception e) {
            print("Exception while parsing L2TunnelPolicy : {}", e);
            return;
        }

        L2TunnelDescription pw = new DefaultL2TunnelDescription(tun, policy);
        L2TunnelHandler.Result res = srService.addPseudowire(pw);

        switch (res) {
            case ADDITION_ERROR:
                print("Pseudowire could not be added, please check logs for more details!");
                break;
            case SUCCESS:
                print("Pseudowire was added succesfully!");
                break;
            default:
                break;
        }

    }
}