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

import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.Member;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.intf.Interface;
import org.onosproject.incubator.net.virtual.TenantId;
import org.onosproject.incubator.net.virtual.VirtualDevice;
import org.onosproject.incubator.net.virtual.VirtualNetwork;
import org.onosproject.incubator.net.virtual.VirtualPort;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Element;
import org.onosproject.net.ElementId;
import org.onosproject.net.Port;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.group.Group;
import org.onosproject.net.key.DeviceKey;
import org.onosproject.net.region.Region;
import org.onosproject.net.statistic.FlowEntryWithLoad;
import org.onosproject.net.topology.TopologyCluster;
import org.onosproject.ui.model.topo.UiTopoLayout;

import java.util.Comparator;

/**
 * Various comparators.
 */
public final class Comparators {

    // Ban construction
    private Comparators() {
    }

    public static final Comparator<ApplicationId> APP_ID_COMPARATOR =
            (id1, id2) -> id1.id() - id2.id();

    public static final Comparator<Application> APP_COMPARATOR =
            (app1, app2) -> app1.id().id() - app2.id().id();

    public static final Comparator<ElementId> ELEMENT_ID_COMPARATOR =
            (id1, id2) -> id1.toString().compareTo(id2.toString());

    public static final Comparator<Element> ELEMENT_COMPARATOR =
            (e1, e2) -> e1.id().toString().compareTo(e2.id().toString());

    public static final Comparator<FlowRule> FLOW_RULE_COMPARATOR =
            (f1, f2) -> {
                // Compare table IDs in ascending order
                int tableCompare = f1.tableId() - f2.tableId();
                if (tableCompare != 0) {
                    return tableCompare;
                }
                // Compare priorities in descending order
                int priorityCompare = f2.priority() - f1.priority();
                return (priorityCompare == 0)
                        ? Long.valueOf(f1.id().value()).compareTo(f2.id().value())
                        : priorityCompare;
            };

    public static final Comparator<FlowEntryWithLoad> FLOWENTRY_WITHLOAD_COMPARATOR =
            (fe1, fe2) -> {
                long delta = fe1.load().rate() - fe2.load().rate();
                return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
            };

    public static final Comparator<Group> GROUP_COMPARATOR =
            (g1, g2) -> Long.valueOf(g1.id().id()).compareTo((long) g2.id().id());

    public static final Comparator<Port> PORT_COMPARATOR =
            (p1, p2) -> {
                long delta = p1.number().toLong() - p2.number().toLong();
                return delta == 0 ? 0 : (delta < 0 ? -1 : +1);
            };

    public static final Comparator<TopologyCluster> CLUSTER_COMPARATOR =
            (c1, c2) -> c1.id().index() - c2.id().index();

    public static final Comparator<ControllerNode> NODE_COMPARATOR =
            (ci1, ci2) -> ci1.id().toString().compareTo(ci2.id().toString());

    public static final Comparator<Member> MEMBERSHIP_COMPARATOR =
            (ci1, ci2) -> ci1.nodeId().toString().compareTo(ci2.nodeId().toString());

    public static final Comparator<ConnectPoint> CONNECT_POINT_COMPARATOR =
            (o1, o2) -> {
                int compareId = ELEMENT_ID_COMPARATOR.compare(o1.elementId(), o2.elementId());
                return (compareId != 0) ?
                        compareId :
                        Long.signum(o1.port().toLong() - o2.port().toLong());
            };

    public static final Comparator<Interface> INTERFACES_COMPARATOR =
            (intf1, intf2) ->
                    CONNECT_POINT_COMPARATOR.compare(intf1.connectPoint(), intf2.connectPoint());

    public static final Comparator<DeviceKey> DEVICE_KEY_COMPARATOR =
            (dk1, dk2) -> dk1.deviceKeyId().id().compareTo(dk2.deviceKeyId().id());

    public static final Comparator<Region> REGION_COMPARATOR =
            (r1, r2) -> r1.id().toString().compareTo(r2.id().toString());

    public static final Comparator<UiTopoLayout> LAYOUT_COMPARATOR =
            (l1, l2) -> l1.id().toString().compareTo(l2.id().toString());

    public static final Comparator<TenantId> TENANT_ID_COMPARATOR =
            (t1, t2) -> t1.id().compareTo(t2.id());

    public static final Comparator<VirtualNetwork> VIRTUAL_NETWORK_COMPARATOR =
            (v1, v2) -> {
                int compareId = v1.tenantId().toString().compareTo(v2.tenantId().toString());
                return (compareId != 0) ? compareId : Long.signum(v1.id().id() - v2.id().id());
            };

    public static final Comparator<VirtualDevice> VIRTUAL_DEVICE_COMPARATOR =
            (v1, v2) -> v1.id().toString().compareTo(v2.id().toString());

    public static final Comparator<VirtualPort> VIRTUAL_PORT_COMPARATOR =
            (v1, v2) -> v1.number().toString().compareTo(v2.number().toString());
}
