/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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.ui.impl.topo;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.Device;
import org.onosproject.net.Host;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.host.HostService;
import org.onosproject.ui.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.HostId.hostId;

/**
 * Encapsulates a selection of devices and/or hosts from the topology view.
 */
public class NodeSelection {

    protected static final Logger log =
            LoggerFactory.getLogger(NodeSelection.class);

    private static final String IDS = "ids";
    private static final String HOVER = "hover";

    private final DeviceService deviceService;
    private final HostService hostService;

    private final Set<String> ids;
    private final String hover;

    private final Set<Device> devices = new HashSet<>();
    private final Set<Host> hosts = new HashSet<>();

    /**
     * Creates a node selection entity, from the given payload, using the
     * supplied device and host services.
     *
     * @param payload message payload
     * @param deviceService device service
     * @param hostService host service
     */
    public NodeSelection(ObjectNode payload,
                         DeviceService deviceService,
                         HostService hostService) {
        this.deviceService = deviceService;
        this.hostService = hostService;

        ids = extractIds(payload);
        hover = extractHover(payload);

        Set<String> unmatched = findDevices(ids);
        unmatched = findHosts(unmatched);
        if (unmatched.size() > 0) {
            log.debug("Skipping unmatched IDs {}", unmatched);
        }

        if (!isNullOrEmpty(hover)) {
            unmatched = new HashSet<>();
            unmatched.add(hover);
            unmatched = findDevices(unmatched);
            unmatched = findHosts(unmatched);
            if (unmatched.size() > 0) {
                log.debug("Skipping unmatched HOVER {}", unmatched);
            }
        }
    }

    /**
     * Returns a view of the selected devices.
     *
     * @return selected devices
     */
    public Set<Device> devices() {
        return Collections.unmodifiableSet(devices);
    }

    /**
     * Returns a view of the selected hosts.
     *
     * @return selected hosts
     */
    public Set<Host> hosts() {
        return Collections.unmodifiableSet(hosts);
    }

    /**
     * Returns true if nothing is selected.
     *
     * @return true if nothing selected
     */
    public boolean none() {
        return devices().size() == 0 && hosts().size() == 0;
    }

    @Override
    public String toString() {
        return "NodeSelection{" +
                "ids=" + ids +
                ", hover='" + hover + '\'' +
                ", #devices=" + devices.size() +
                ", #hosts=" + hosts.size() +
                '}';
    }

    // == helper methods

    private Set<String> extractIds(ObjectNode payload) {
        ArrayNode array = (ArrayNode) payload.path(IDS);
        if (array == null || array.size() == 0) {
            return Collections.emptySet();
        }

        Set<String> ids = new HashSet<>();
        for (JsonNode node : array) {
            ids.add(node.asText());
        }
        return ids;
    }

    private String extractHover(ObjectNode payload) {
        return JsonUtils.string(payload, HOVER);
    }

    private Set<String> findDevices(Set<String> ids) {
        Set<String> unmatched = new HashSet<>();
        Device device;

        for (String id : ids) {
            try {
                device = deviceService.getDevice(deviceId(id));
                if (device != null) {
                    devices.add(device);
                } else {
                    log.debug("Device with ID {} not found", id);
                }
            } catch (IllegalArgumentException e) {
                unmatched.add(id);
            }
        }
        return unmatched;
    }

    private Set<String> findHosts(Set<String> ids) {
        Set<String> unmatched = new HashSet<>();
        Host host;

        for (String id : ids) {
            try {
                host = hostService.getHost(hostId(id));
                if (host != null) {
                    hosts.add(host);
                } else {
                    log.debug("Host with ID {} not found", id);
                }
            } catch (IllegalArgumentException e) {
                unmatched.add(id);
            }
        }
        return unmatched;
    }

}
