/*
 * 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;
    private final boolean secretChanged;

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

         boolean haveOldSecret = (oldValue != null && oldValue.getClusterSecret() != null);
         boolean haveNewSecret = (newValue != null && newValue.getClusterSecret() != null);

         if (!haveOldSecret && haveNewSecret) {
             secretChanged = true;
         } else if (haveOldSecret && haveNewSecret &&
                 !oldValue.getClusterSecret().equals(newValue.getClusterSecret())) {
             secretChanged = true;
         } else if (haveOldSecret && !haveNewSecret) {
             secretChanged = true;
         } else {
             secretChanged = false;
         }
     }

    /**
     * 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 whether the cluster-wide shared secret changed.
     * @return  whether the cluster secret changed
     */
    public boolean clusterSecretChanged() {
        return secretChanged;
    }

    /**
     * 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;
    }
}
