/*
 * 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 com.google.common.collect.ImmutableSet;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.IpAddress;
import org.onlab.util.Tools;
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.provider.nil.CustomTopologySimulator;
import org.onosproject.provider.nil.NullProviders;
import org.onosproject.provider.nil.TopologySimulator;

import java.util.Set;

import static java.util.Objects.requireNonNull;

/**
 * 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 CreateNullEntity {

    @Argument(index = 0, name = "deviceNames", description = "Name of device where host is attached; comma-separated",
            required = true)
    String deviceNames = null;

    @Argument(index = 1, name = "hostIps", description = "Host IP addresses; comma-separated",
            required = true)
    String hostIps = null;

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

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

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

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

        TopologySimulator simulator = service.currentSimulator();
        if (!validateSimulator(simulator) || !validateLocType(locType)) {
            return;
        }

        CustomTopologySimulator sim = (CustomTopologySimulator) simulator;
        HostId id = sim.nextHostId();
        Set<HostLocation> locations = getLocations(sim, deviceNames);
        Set<IpAddress> ips = getIps(hostIps);

        BasicHostConfig cfg = cfgService.addConfig(id, BasicHostConfig.class);
        setUiCoordinates(cfg, locType, latOrY, longOrX);

        Tools.delay(10);
        sim.createHost(id, locations, ips);
    }

    private Set<IpAddress> getIps(String hostIps) {
        ImmutableSet.Builder<IpAddress> ips = ImmutableSet.builder();
        String[] csv = hostIps.split(",");
        for (String s : csv) {
            ips.add(IpAddress.valueOf(s));
        }
        return ips.build();
    }

    private Set<HostLocation> getLocations(CustomTopologySimulator sim, String deviceNames) {
        ImmutableSet.Builder<HostLocation> locations = ImmutableSet.builder();
        String[] csv = deviceNames.split(",");
        for (String s : csv) {
            locations.add(requireNonNull(findAvailablePort(sim.deviceId(s))));
        }
        return locations.build();
    }

    // Finds an available connect point among edge ports of the specified device
    private HostLocation findAvailablePort(DeviceId deviceId) {
        ConnectPoint point = findAvailablePort(deviceId, null);
        return point == null ? null : new HostLocation(point, System.currentTimeMillis());
    }

}
