/*
 * Copyright 2014 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.onlab.onos.net;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

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

/**
 * Represents a set of simple annotations that can be used to add arbitrary
 * attributes to various parts of the data model.
 */
public final class DefaultAnnotations implements SparseAnnotations {

    private final Map<String, String> map;

    // For serialization
    private DefaultAnnotations() {
        this.map = null;
    }

    /**
     * Creates a new set of annotations using clone of the specified hash map.
     *
     * @param map hash map of key/value pairs
     */
    private DefaultAnnotations(Map<String, String> map) {
        this.map = map;
    }

    /**
     * Creates a new annotations builder.
     *
     * @return new annotations builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Merges the specified base set of annotations and additional sparse
     * annotations into new combined annotations. If the supplied sparse
     * annotations are empty, the original base annotations are returned.
     * Any keys tagged for removal in the sparse annotations will be omitted
     * in the resulting merged annotations.
     *
     * @param annotations       base annotations
     * @param sparseAnnotations additional sparse annotations
     * @return combined annotations or the original base annotations if there
     * are not additional annotations
     */
    public static DefaultAnnotations merge(DefaultAnnotations annotations,
                                           SparseAnnotations sparseAnnotations) {
        checkNotNull(annotations, "Annotations cannot be null");
        if (sparseAnnotations == null || sparseAnnotations.keys().isEmpty()) {
            return annotations;
        }

        // Merge the two maps. Yes, this is not very efficient, but the
        // use-case implies small maps and infrequent merges, so we opt for
        // simplicity.
        Map<String, String> merged = copy(annotations.map);
        for (String key : sparseAnnotations.keys()) {
            if (sparseAnnotations.isRemoved(key)) {
                merged.remove(key);
            } else {
                merged.put(key, sparseAnnotations.value(key));
            }
        }
        return new DefaultAnnotations(merged);
    }

    /**
     * Creates the union of two given SparseAnnotations.
     * Unlike the {@link #merge(DefaultAnnotations, SparseAnnotations)} method,
     * result will be {@link SparseAnnotations} instead of {@link Annotations}.
     *
     * A key tagged for removal will remain in the output SparseAnnotations,
     * if the counterpart of the input does not contain the same key.
     *
     * @param annotations       base annotations
     * @param sparseAnnotations additional sparse annotations
     * @return combined annotations or the original base annotations if there
     * are not additional annotations
     */
    public static SparseAnnotations union(SparseAnnotations annotations,
                                          SparseAnnotations sparseAnnotations) {

        if (sparseAnnotations == null || sparseAnnotations.keys().isEmpty()) {
            return annotations;
        }

        final HashMap<String, String> newMap;
        if (annotations instanceof DefaultAnnotations) {
            newMap = copy(((DefaultAnnotations) annotations).map);
        } else {
            newMap = new HashMap<>(annotations.keys().size() +
                                   sparseAnnotations.keys().size());
            putAllSparseAnnotations(newMap, annotations);
        }

        putAllSparseAnnotations(newMap, sparseAnnotations);
        return new DefaultAnnotations(newMap);
    }

    // adds the key-values contained in sparseAnnotations to
    // newMap, if sparseAnnotations had a key tagged for removal,
    // and corresponding key exist in newMap, entry will be removed.
    // if corresponding key does not exist, removal tag will be added to
    // the newMap.
    private static void putAllSparseAnnotations(
                            final HashMap<String, String> newMap,
                            SparseAnnotations sparseAnnotations) {

        for (String key : sparseAnnotations.keys()) {
            if (sparseAnnotations.isRemoved(key)) {
                if (newMap.containsKey(key)) {
                    newMap.remove(key);
                } else {
                    newMap.put(key, Builder.REMOVED);
                }
            } else {
                String value = sparseAnnotations.value(key);
                newMap.put(key, value);
            }
        }
    }

    @Override
    public Set<String> keys() {
        return Collections.unmodifiableSet(map.keySet());
    }

    @Override
    public String value(String key) {
        String value = map.get(key);
        return Objects.equals(Builder.REMOVED, value) ? null : value;
    }

    @Override
    public boolean isRemoved(String key) {
        return Objects.equals(Builder.REMOVED, map.get(key));
    }

    @SuppressWarnings("unchecked")
    private static HashMap<String, String> copy(Map<String, String> original) {
        if (original instanceof HashMap) {
            return (HashMap<String, String>) ((HashMap<?, ?>) original).clone();
        }
        throw new IllegalArgumentException("Expecting HashMap instance");
    }

    /**
     * Facility for gradually building model annotations.
     */
    public static final class Builder {

        private static final String REMOVED = "~rEmOvEd~";
        private final Map<String, String> builder = new HashMap<>();

        // Private construction is forbidden.
        private Builder() {
        }

        /**
         * Adds the specified annotation. Any previous value associated with
         * the given annotation key will be overwritten.
         *
         * @param key   annotation key
         * @param value annotation value
         * @return self
         */
        public Builder set(String key, String value) {
            builder.put(key, value);
            return this;
        }

        /**
         * Adds the specified annotation. Any previous value associated with
         * the given annotation key will be tagged for removal.
         *
         * @param key annotation key
         * @return self
         */
        public Builder remove(String key) {
            builder.put(key, REMOVED);
            return this;
        }

        /**
         * Returns immutable annotations built from the accrued key/values pairs.
         *
         * @return annotations
         */
        public DefaultAnnotations build() {
            return new DefaultAnnotations(copy(builder));
        }
    }
}
