/*
 * Copyright 2017-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.ui.lion;

import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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

/**
 * Encapsulates a bundle of localization strings.
 */
public final class LionBundle {

    private final String id;
    private final Set<LionItem> items;
    private final Map<String, String> mapped;

    private LionBundle(String id, Set<LionItem> items) {
        this.id = id;
        this.items = ImmutableSortedSet.copyOf(items);
        mapped = createLookup();
    }

    private Map<String, String> createLookup() {
        Map<String, String> lookup = new HashMap<>(items.size());
        for (LionItem item : items) {
            lookup.put(item.key(), item.value());
        }
        return ImmutableSortedMap.copyOf(lookup);
    }

    /**
     * Returns the bundle's identifier.
     *
     * @return the bundle's ID
     */
    public String id() {
        return id;
    }

    /**
     * Returns the number of entries in this bundle.
     *
     * @return number of entries
     */
    public int size() {
        return items.size();
    }

    @Override
    public String toString() {
        return "LionBundle{id=" + id + ", #items=" + size() + "}";
    }

    /**
     * Returns the localized value for the given key, or null if no such
     * mapping exists.
     *
     * @param key the key
     * @return the localized value
     */
    public String getValue(String key) {
        return mapped.get(key);
    }

    /**
     * Returns the localized value for the given key, or, if no such mapping
     * exists, returns the key wrapped in '%' characters.
     *
     * @param key the key
     * @return the localized value (or a wrapped key placeholder)
     */
    public String getSafe(String key) {
        String value = mapped.get(key);
        return value == null ? "%" + key + "%" : value;
    }

    /**
     * Returns an immutable set of the items in this bundle.
     *
     * @return the items in this bundle
     */
    public Set<LionItem> getItems() {
        return items;
    }

    /**
     * Dump the contents of the bundle.
     *
     * @return dumped contents
     */
    public String dump() {
        return mapped.toString();
    }

    // === --------------------------------------------------------------------

    /**
     * Builder of Lion Bundles.
     */
    public static final class Builder {
        private final String id;
        private final Set<LionItem> items = new HashSet<>();

        /**
         * Creates a builder of Lion Bundles.
         *
         * @param id the bundle's identifier
         */
        public Builder(String id) {
            this.id = id;
        }

        /**
         * Returns the bundle ID.
         *
         * @return the bundle ID
         */
        public String id() {
            return id;
        }

        /**
         * Adds an item to the bundle.
         *
         * @param key   the item key
         * @param value the item value
         * @return self, for chaining
         */
        public Builder addItem(String key, String value) {
            items.add(new LionItem(key, value));
            return this;
        }

        /**
         * Builds the lion bundle from this builder instance.
         *
         * @return the lion bundle
         */
        public LionBundle build() {
            return new LionBundle(id, items);
        }
    }

    // === --------------------------------------------------------------------

    /**
     * Represents a single localization item.
     */
    public static final class LionItem implements Comparable<LionItem> {
        private final String key;
        private final String value;

        /**
         * Creates a lion item with the given key and value.
         *
         * @param key   the key
         * @param value the value
         */
        private LionItem(String key, String value) {
            checkNotNull(key);
            checkNotNull(value);
            this.key = key;
            this.value = value;
        }

        @Override
        public String toString() {
            return "LionItem{key=" + key + ", value=\"" + value + "\"}";
        }

        @Override
        public int compareTo(LionItem o) {
            return key.compareTo(o.key);
        }

        /**
         * Returns the key.
         *
         * @return the key
         */
        public String key() {
            return key;
        }

        /**
         * Returns the value.
         *
         * @return the value
         */
        public String value() {
            return value;
        }
    }
}
