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

        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());
    }

}
