/*
 * Copyright 2016-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.pce.cli;

import static org.onosproject.net.Link.State.ACTIVE;
import static org.onosproject.net.Link.Type.DIRECT;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.Collection;
import java.util.List;
import java.util.LinkedList;

import com.google.common.collect.Lists;

import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Option;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.onlab.util.DataRateUnit;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.tunnel.Tunnel;
import org.onosproject.incubator.net.tunnel.TunnelService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultLink;
import org.onosproject.net.DeviceId;
import org.onosproject.net.NetworkResource;
import org.onosproject.net.PortNumber;
import org.onosproject.net.intent.Constraint;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.pce.pceservice.ExplicitPathInfo;
import org.onosproject.pce.pceservice.constraint.CostConstraint;
import org.onosproject.pce.pceservice.LspType;
import org.onosproject.pce.pceservice.api.PceService;
import org.onosproject.pce.pceservice.constraint.PceBandwidthConstraint;
import org.slf4j.Logger;

/**
 * Supports creating the pce path.
 */
@Service
@Command(scope = "onos", name = "pce-setup-path", description = "Supports creating pce path.")
public class PceSetupPathCommand extends AbstractShellCommand {
    private final Logger log = getLogger(getClass());
    public static final byte SUBTYPE_DEVICEID = 0;
    public static final byte SUBTYPE_LINK = 1;
    public static final byte SUBTYPE_INDEX = 1;
    public static final byte TYPE_INDEX = 0;

    public static final byte DEVICEID_INDEX = 2;
    public static final byte SOURCE_DEVICEID_INDEX = 2;
    public static final byte SOURCE_PORTNO_INDEX = 3;
    public static final byte DESTINATION_DEVICEID_INDEX = 4;
    public static final byte DESTINATION_PORTNO_INDEX = 5;

    @Argument(index = 0, name = "src", description = "source device.", required = true, multiValued = false)
    String src = null;

    @Argument(index = 1, name = "dst", description = "destination device.", required = true, multiValued = false)
    String dst = null;

    @Argument(index = 2, name = "type", description = "LSP type:" + " It includes "
            + "PCE tunnel with signalling in network (0), "
            + "PCE tunnel without signalling in network with segment routing (1), "
            + "PCE tunnel without signalling in network (2).",
            required = true, multiValued = false)
    int type = 0;

    @Argument(index = 3, name = "name", description = "symbolic-path-name.", required = true, multiValued = false)
    String name = null;

    @Option(name = "-c", aliases = "--cost", description = "The cost attribute IGP cost(1) or TE cost(2)",
            required = false, multiValued = false)
    int cost = 2;

    @Option(name = "-b", aliases = "--bandwidth", description = "The bandwidth attribute of path. "
            + "Data rate unit is in BPS.", required = false, multiValued = false)
    double bandwidth = 0.0;

    @Option(name = "-e", aliases = "--explicitPathObjects", description = "List of strict and loose hopes"
            + " explicitPathInfo format : Type/SubType/Value(DeviceId or Link info)\n" +
            " If Value is Device : Type/SubType/deviceId\n" +
            " If Value is Link : Type/SubType/SourceDeviceId/SourcePortNo/DestinationDeviceId/DestinationPortNo" +
            "Type 0 - strict, 1 - loose \n" + "SubType 0 - deviceId, 1 - link \n",
            required = false, multiValued = true)
    String[] explicitPathInfoStrings;

    @Option(name = "-l", aliases = "--loadBalancing", description = "The load balancing option for user. ",
            required = false, multiValued = false)
    boolean loadBalancing = false;

    //explicitPathInfo format : Type/SubType/Value(DeviceId or Link info)
    //If Value is Device : Type/SubType/deviceId
    //If Value is Link : Type/SubType/SourceDeviceId/SourcePortNo/DestinationDeviceId/DestinationPortNo
    List<ExplicitPathInfo> explicitPathInfo = Lists.newLinkedList();

    @Override
    protected void doExecute() {
        log.info("executing pce-setup-path");

        PceService service = get(PceService.class);
        TunnelService tunnelService = get(TunnelService.class);

        DeviceId srcDevice = DeviceId.deviceId(src);
        DeviceId dstDevice = DeviceId.deviceId(dst);
        List<Constraint> listConstrnt = new LinkedList<>();

        // LSP type validation
        if ((type < 0) || (type > 2)) {
           error("The LSP type value can be PCE tunnel with signalling in network (0), " +
                 "PCE tunnel without signalling in network with segment routing (1), " +
                 "PCE tunnel without signalling in network (2).");
           return;
        }
        LspType lspType = LspType.values()[type];

        //Validating tunnel name, duplicated tunnel names not allowed
        Collection<Tunnel> existingTunnels = tunnelService.queryTunnel(Tunnel.Type.MPLS);
        for (Tunnel t : existingTunnels) {
            if (t.tunnelName().toString().equals(name)) {
                error("Path creation failed, Tunnel name already exists");
                return;
            }
        }

        // Add bandwidth
        // bandwidth default data rate unit is in BPS
        if (bandwidth != 0.0) {
            listConstrnt.add(PceBandwidthConstraint.of(bandwidth, DataRateUnit.valueOf("BPS")));
        }

        // Add cost
        // Cost validation
        if ((cost < 1) || (cost > 2)) {
            error("The cost attribute value either IGP cost(1) or TE cost(2).");
            return;
        }
        // Here 'cost - 1' indicates the index of enum
        CostConstraint.Type costType = CostConstraint.Type.values()[cost - 1];
        listConstrnt.add(CostConstraint.of(costType));

        if (explicitPathInfoStrings != null)  {
            for (String str : explicitPathInfoStrings) {
                String[] splitted = str.split("/");
                DeviceId deviceId;
                NetworkResource res = null;
                PortNumber portNo;
                int explicitPathType = Integer.parseInt(splitted[TYPE_INDEX]);
                if ((explicitPathType < 0) || (explicitPathType > 1)) {
                    error("Explicit path validation failed");
                    return;
                }

                //subtype 0 = deviceId, 1 = link
                //subtype is required to store either as deviceId or Link
                if (splitted[DEVICEID_INDEX] != null && Integer.parseInt(splitted[SUBTYPE_INDEX]) == SUBTYPE_DEVICEID) {
                    res = DeviceId.deviceId(splitted[DEVICEID_INDEX]);
                } else if (Integer.parseInt(splitted[SUBTYPE_INDEX]) == SUBTYPE_LINK
                        && splitted[SOURCE_DEVICEID_INDEX] != null
                        && splitted[SOURCE_PORTNO_INDEX] != null
                        && splitted[DESTINATION_DEVICEID_INDEX] != null
                        && splitted[DESTINATION_PORTNO_INDEX] != null) {

                    deviceId = DeviceId.deviceId(splitted[SOURCE_DEVICEID_INDEX]);
                    portNo = PortNumber.portNumber(splitted[SOURCE_PORTNO_INDEX]);
                    ConnectPoint cpSrc = new ConnectPoint(deviceId, portNo);
                    deviceId = DeviceId.deviceId(splitted[DESTINATION_DEVICEID_INDEX]);
                    portNo = PortNumber.portNumber(splitted[DESTINATION_PORTNO_INDEX]);
                    ConnectPoint cpDst = new ConnectPoint(deviceId, portNo);
                    res = DefaultLink.builder()
                            .providerId(ProviderId.NONE)
                            .src(cpSrc)
                            .dst(cpDst)
                            .type(DIRECT)
                            .state(ACTIVE)
                            .build();
                } else {
                    error("Explicit path validation failed");
                    return;
                }
                ExplicitPathInfo obj = new ExplicitPathInfo(ExplicitPathInfo.Type.values()[explicitPathType], res);
                explicitPathInfo.add(obj);
            }
        }

        //with load balancing option
        if (loadBalancing) {
            if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType, loadBalancing)) {
                error("Path creation failed.");
            }
            return;
        }

        if (!service.setupPath(srcDevice, dstDevice, name, listConstrnt, lspType, explicitPathInfo)) {
            error("Path creation failed.");
        }
    }
}
