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

import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.IpAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.BasicHostConfig;
import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.host.HostService;
import org.onosproject.provider.nil.CustomTopologySimulator;
import org.onosproject.provider.nil.NullProviders;
import org.onosproject.provider.nil.TopologySimulator;

import java.util.HashSet;
import java.util.Iterator;

/**
 * Adds a simulated end-station host to the custom topology simulation.
 */
@Command(scope = "onos", name = "null-create-host",
        description = "Adds a simulated end-station host to the custom topology simulation")
public class CreateNullHost extends AbstractShellCommand {
    private static final String GEO = "geo";
    private static final String GRID = "grid";

    @Argument(index = 0, name = "deviceName", description = "Name of device where host is attached",
            required = true, multiValued = false)
    String deviceName = null;

    @Argument(index = 1, name = "hostIp", description = "Host IP address",
            required = true, multiValued = false)
    String hostIp = null;

    @Argument(index = 2, name = "latOrY",
            description = "Geo latitude / Grid y-coord",
            required = true, multiValued = false)
    Double latOrY = null;

    @Argument(index = 3, name = "longOrX",
            description = "Geo longitude / Grid x-coord",
            required = true, multiValued = false)
    Double longOrX = null;

    @Argument(index = 4, name = "locType", description = "Location type {geo|grid}",
            required = false, multiValued = false)
    String locType = GEO;

    @Override
    protected void execute() {
        NullProviders service = get(NullProviders.class);
        NetworkConfigService cfgService = get(NetworkConfigService.class);

        TopologySimulator simulator = service.currentSimulator();
        if (!(simulator instanceof CustomTopologySimulator)) {
            error("Custom topology simulator is not active.");
            return;
        }

        if (!(GEO.equals(locType) || GRID.equals(locType))) {
            error("locType must be 'geo' or 'grid'.");
            return;
        }

        CustomTopologySimulator sim = (CustomTopologySimulator) simulator;
        DeviceId deviceId = sim.deviceId(deviceName);
        HostId id = sim.nextHostId();
        HostLocation location = findAvailablePort(deviceId);
        BasicHostConfig cfg = cfgService.addConfig(id, BasicHostConfig.class);

        cfg.locType(locType);
        cfg.setLocations(new HashSet<HostLocation>() {{ add(location); }});

        if (GEO.equals(locType)) {
            cfg.latitude(latOrY).longitude(longOrX);
        } else {
            cfg.gridX(longOrX).gridY(latOrY);
        }
        cfg.apply();

        sim.createHost(id, location, IpAddress.valueOf(hostIp));
    }

    // Finds an available connect point among edge ports of the specified device
    private HostLocation findAvailablePort(DeviceId deviceId) {
        EdgePortService eps = get(EdgePortService.class);
        HostService hs = get(HostService.class);
        Iterator<ConnectPoint> points = eps.getEdgePoints(deviceId).iterator();

        while (points.hasNext()) {
            ConnectPoint point = points.next();
            if (hs.getConnectedHosts(point).isEmpty()) {
                return new HostLocation(point, System.currentTimeMillis());
            }
        }
        return null;
    }

}
