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

import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Verify.verifyNotNull;
import static com.google.common.base.Verify.verify;

import com.google.common.base.MoreObjects;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

/**
 * Cluster metadata.
 * <p>
 * Metadata specifies the attributes that define a ONOS cluster and comprises the collection
 * of {@link org.onosproject.cluster.ControllerNode nodes} and the collection of data
 * {@link org.onosproject.cluster.Partition partitions}.
 */
public final class ClusterMetadata {

    // Name to use when the ClusterMetadataService is in transient state
    public static final String NO_NAME = "";

    private String name;
    private Set<ControllerNode> nodes;
    private Set<Partition> partitions;

    /**
     * Returns a new cluster metadata builder.
     * @return The cluster metadata builder.
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Returns the name of the cluster.
     *
     * @return cluster name
     */
    public String getName() {
        return this.name;
    }

    /**
     * Returns the collection of {@link org.onosproject.cluster.ControllerNode nodes} that make up the cluster.
     * @return cluster nodes
     */
    public Collection<ControllerNode> getNodes() {
        return this.nodes;
    }

    /**
     * Returns the collection of data {@link org.onosproject.cluster.Partition partitions} that make up the cluster.
     * @return collection of partitions.
     */
    public Collection<Partition> getPartitions() {
        return this.partitions;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(ClusterMetadata.class)
                .add("name", name)
                .add("nodes", nodes)
                .add("partitions", partitions)
                .toString();
    }

    @Override
    public int hashCode() {
        return Arrays.deepHashCode(new Object[] {name, nodes, partitions});
    }

    /*
     * Provide a deep quality check of the meta data (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object object) {

        if (!ClusterMetadata.class.isInstance(object)) {
            return false;
        }
        ClusterMetadata that = (ClusterMetadata) object;

        if (!this.name.equals(that.name) || this.nodes.size() != that.nodes.size()
                || this.partitions.size() != that.partitions.size()) {
            return false;
        }

        return Sets.symmetricDifference(this.nodes, that.nodes).isEmpty()
                && Sets.symmetricDifference(this.partitions, that.partitions).isEmpty();
    }

    /**
     * Builder for a {@link ClusterMetadata} instance.
     */
    public static class Builder {

        private final ClusterMetadata metadata;

        public Builder() {
            metadata = new ClusterMetadata();
        }

        /**
         * Sets the cluster name, returning the cluster metadata builder for method chaining.
         * @param name cluster name
         * @return this cluster metadata builder
         */
        public Builder withName(String name) {
            metadata.name = checkNotNull(name);
            return this;
        }

        /**
         * Sets the collection of cluster nodes, returning the cluster metadata builder for method chaining.
         * @param controllerNodes collection of cluster nodes
         * @return this cluster metadata builder
         */
        public Builder withControllerNodes(Collection<ControllerNode> controllerNodes) {
            metadata.nodes = ImmutableSet.copyOf(checkNotNull(controllerNodes));
            return this;
        }

        /**
         * Sets the collection of data partitions, returning the cluster metadata builder for method chaining.
         * @param partitions collection of partitions
         * @return this cluster metadata builder
         */
        public Builder withPartitions(Collection<Partition> partitions) {
            metadata.partitions = ImmutableSet.copyOf(checkNotNull(partitions));
            return this;
        }

        /**
         * Builds the cluster metadata.
         * @return cluster metadata
         * @throws com.google.common.base.VerifyException VerifyException if the metadata is misconfigured
         */
        public ClusterMetadata build() {
            verifyMetadata();
            return metadata;
        }

        /**
         * Validates the constructed metadata for semantic correctness.
         * @throws VerifyException if the metadata is misconfigured.
         */
        private void verifyMetadata() {
            verifyNotNull(metadata.getName(), "Cluster name must be specified");
            verifyNotNull(metadata.getNodes(), "Cluster nodes must be specified");
            verifyNotNull(metadata.getPartitions(), "Cluster partitions must be specified");
            verify(!metadata.getNodes().isEmpty(), "Cluster nodes must not be empty");
            verify(!metadata.getPartitions().isEmpty(), "Cluster nodes must not be empty");

            // verify that partitions are constituted from valid cluster nodes.
            boolean validPartitions = Collections2.transform(metadata.getNodes(), ControllerNode::id)
                    .containsAll(metadata.getPartitions()
                            .stream()
                            .flatMap(r -> r.getMembers().stream())
                            .collect(Collectors.toSet()));
            verify(validPartitions, "Partition locations must be valid cluster nodes");
        }
    }
}
