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

import static com.google.common.base.Preconditions.checkState;

import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * Utility for examining differences between two {@link ClusterMetadata metadata} values.
 *
 * @deprecated since 1.14
 */
@Deprecated
public class ClusterMetadataDiff {

    private final ClusterMetadata oldValue;
    private final ClusterMetadata newValue;
    private final Set<ControllerNode> nodesAdded;
    private final Set<NodeId> nodesRemoved;

     public ClusterMetadataDiff(ClusterMetadata oldValue, ClusterMetadata newValue) {
         this.oldValue = oldValue;
         this.newValue = newValue;

         Set<ControllerNode> currentNodeSet = oldValue == null
                 ? ImmutableSet.of() : ImmutableSet.copyOf(oldValue.getNodes());
         Set<ControllerNode> newNodeSet = newValue == null
                 ? ImmutableSet.of() : ImmutableSet.copyOf(newValue.getNodes());
         nodesAdded = Sets.difference(newNodeSet, currentNodeSet);
         nodesRemoved = Sets.difference(currentNodeSet, newNodeSet)
                            .stream()
                            .map(ControllerNode::id)
                            .collect(Collectors.toSet());
     }

    /**
     * Returns the set of {@link ControllerNode nodes} added with this metadata change.
     * @return set of controller nodes
     */
    public Set<ControllerNode> nodesAdded() {
        return nodesAdded;
    }

    /**
     * Returns the set of {@link ControllerNode nodes} removed with this metadata change.
     * @return set of controller node identifiers
     */
    public Set<NodeId> nodesRemoved() {
        return nodesRemoved;
    }

    /**
     * Returns a mapping of all partition diffs.
     * @return partition diffs.
     */
    public Map<PartitionId, PartitionDiff> partitionDiffs() {
        Map<PartitionId, Partition> oldPartitions = Maps.newHashMap();
        oldValue.getPartitions()
                .forEach(p -> oldPartitions.put(p.getId(), p));
        Map<PartitionId, Partition> newPartitions = Maps.newHashMap();
        newValue.getPartitions()
                .forEach(p -> newPartitions.put(p.getId(), p));
        checkState(Sets.symmetricDifference(oldPartitions.keySet(), newPartitions.keySet()).isEmpty(),
                   "Number of partitions cannot change");
        Map<PartitionId, PartitionDiff> partitionDiffs = Maps.newHashMap();
        oldPartitions.forEach((k, v) -> {
            partitionDiffs.put(k, new PartitionDiff(v, newPartitions.get(k)));
        });
        return partitionDiffs;
    }
}
