/*
 * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

package org.eclipse.persistence.internal.oxm;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import java.util.function.BiFunction;

import static org.eclipse.persistence.internal.oxm.VectorUtils.emptyVector;
import static org.eclipse.persistence.internal.oxm.VectorUtils.unmodifiableVector;

public class NamespaceResolverStorage extends LinkedHashMap<String, String> {
    private static final long serialVersionUID = -4697397620139076774L;
    private transient Vector<Namespace> namespaces = emptyVector();
    private transient boolean modified = false;

    public NamespaceResolverStorage() {
        super();
    }

    public NamespaceResolverStorage(int initialCapacity) {
        super(initialCapacity);
    }

    @Override
    public String put(String key, String value) {
        String response = super.put(key, value);
        setModified();
        return response;
    }

    private void setModified() {
        setModified(true);
    }

    @Override
    public void putAll(Map<? extends String, ? extends String> m) {
        super.putAll(m);
        setModified();
    }

    @Override
    public String remove(Object key) {
        if (containsKey(key)) {
            setModified();
        }

        return super.remove(key);
    }

    @Override
    public String putIfAbsent(String key, String value) {
        String response = super.putIfAbsent(key, value);
        setModified();
        return response;
    }

    @Override
    public boolean remove(Object key, Object value) {
        boolean response = super.remove(key, value);
        if (response) {
            setModified();
        }
        return response;
    }

    @Override
    public boolean replace(String key, String oldValue, String newValue) {
        boolean response = super.replace(key, oldValue, newValue);
        if (response) {
            setModified(response);
        }
        return response;
    }

    @Override
    public String replace(String key, String value) {
        String response = super.replace(key, value);
        setModified();
        return response;
    }

    public Vector<Namespace> getNamespaces() {
        if (isModified()) {
            namespaces = buildNamespacesUnmodifiable();
            setModified(false);
        }
        return namespaces;
    }

    public void setNamespaces(Vector<Namespace> namespaces) {
        super.clear();
        for (Namespace namespace : namespaces) {
            if ((namespace.getPrefix() != null) && (namespace.getNamespaceURI() != null)) {
                super.put(namespace.getPrefix(), namespace.getNamespaceURI());
            }
        }
        setModified();
    }

    private boolean isModified() {
        return modified;
    }

    private void setModified(boolean modified) {
        this.modified = modified;
    }

    private Vector<Namespace> buildNamespacesUnmodifiable() {
        Vector<Namespace> names = new Vector<>(size());
        for (Map.Entry<String, String> entry : entrySet()) {
            Namespace namespace = new Namespace(entry.getKey(), entry.getValue());
            names.addElement(namespace);
        }
        return unmodifiableVector(names);
    }

    /**
     * Unmodifiable set of keys
     */
    @Override
    public Set<String> keySet() {
        return Collections.unmodifiableSet(super.keySet());
    }

    /**
     * Unmodifiable collection of values
     */
    @Override
    public Collection<String> values() {
        return Collections.unmodifiableCollection(super.values());
    }

    /**
     * Unmodifiable set of entries
     */
    @Override
    public Set<Map.Entry<String, String>> entrySet() {
        return Collections.unmodifiableSet(super.entrySet());
    }

    @Override
    public void replaceAll(BiFunction<? super String, ? super String, ? extends String> function) {
        super.replaceAll(function);
        setModified();
    }
}
