/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.commons.configuration2;

import java.util.Iterator;
import java.util.Objects;

import org.apache.commons.configuration2.convert.ListDelimiterHandler;
import org.apache.commons.lang3.StringUtils;

/**
 * <p>
 * A subset of another configuration. The new Configuration object contains every key from the parent Configuration that
 * starts with prefix. The prefix is removed from the keys in the subset.
 * </p>
 * <p>
 * It is usually not necessary to use this class directly. Instead the {@link Configuration#subset(String)} method
 * should be used, which will return a correctly initialized instance.
 * </p>
 */
public class SubsetConfiguration extends AbstractConfiguration {
    /**
     * A specialized iterator to be returned by the {@code getKeys()} methods. This implementation wraps an iterator from
     * the parent configuration. The keys returned by this iterator are correspondingly transformed.
     */
    private final class SubsetIterator implements Iterator<String> {
        /** Stores the wrapped iterator. */
        private final Iterator<String> parentIterator;

        /**
         * Creates a new instance of {@code SubsetIterator} and initializes it with the parent iterator.
         *
         * @param it the iterator of the parent configuration
         */
        public SubsetIterator(final Iterator<String> it) {
            parentIterator = it;
        }

        /**
         * Checks whether there are more elements. Delegates to the parent iterator.
         *
         * @return a flag whether there are more elements
         */
        @Override
        public boolean hasNext() {
            return parentIterator.hasNext();
        }

        /**
         * Returns the next element in the iteration. This is the next key from the parent configuration, transformed to
         * correspond to the point of view of this subset configuration.
         *
         * @return the next element
         */
        @Override
        public String next() {
            return getChildKey(parentIterator.next());
        }

        /**
         * Removes the current element from the iteration. Delegates to the parent iterator.
         */
        @Override
        public void remove() {
            parentIterator.remove();
        }
    }

    /** The parent configuration. */
    protected Configuration parent;

    /** The prefix used to select the properties. */
    protected String prefix;

    /** The prefix delimiter */
    protected String delimiter;

    /**
     * Create a subset of the specified configuration
     *
     * @param parent The parent configuration (must not be <b>null</b>)
     * @param prefix The prefix used to select the properties
     * @throws IllegalArgumentException if the parent configuration is <b>null</b>
     */
    public SubsetConfiguration(final Configuration parent, final String prefix) {
        this(parent, prefix, null);
    }

    /**
     * Create a subset of the specified configuration
     *
     * @param parent The parent configuration (must not be <b>null</b>)
     * @param prefix The prefix used to select the properties
     * @param delimiter The prefix delimiter
     * @throws NullPointerException if the parent configuration is <b>null</b>
     */
    public SubsetConfiguration(final Configuration parent, final String prefix, final String delimiter) {
        this.parent = Objects.requireNonNull(parent, "parent");
        this.prefix = prefix;
        this.delimiter = delimiter;
        initInterpolator();
    }

    @Override
    public void addPropertyDirect(final String key, final Object value) {
        parent.addProperty(getParentKey(key), value);
    }

    @Override
    protected void clearPropertyDirect(final String key) {
        parent.clearProperty(getParentKey(key));
    }

    @Override
    protected boolean containsKeyInternal(final String key) {
        return parent.containsKey(getParentKey(key));
    }

    /**
     * Gets the key in the subset configuration associated to the specified key in the parent configuration.
     *
     * @param key The key in the parent configuration.
     * @return the key in the context of this subset configuration
     */
    protected String getChildKey(final String key) {
        if (!key.startsWith(prefix)) {
            throw new IllegalArgumentException("The parent key '" + key + "' is not in the subset.");
        }
        String modifiedKey = null;
        if (key.length() == prefix.length()) {
            modifiedKey = "";
        } else {
            final int i = prefix.length() + (delimiter != null ? delimiter.length() : 0);
            modifiedKey = key.substring(i);
        }

        return modifiedKey;
    }

    @Override
    protected Iterator<String> getKeysInternal() {
        return new SubsetIterator(parent.getKeys(prefix, delimiter));
    }

    @Override
    protected Iterator<String> getKeysInternal(final String prefix) {
        return new SubsetIterator(parent.getKeys(getParentKey(prefix)));
    }

    /**
     * {@inheritDoc} If the parent configuration extends {@link AbstractConfiguration}, the list delimiter handler is
     * obtained from there.
     */
    @Override
    public ListDelimiterHandler getListDelimiterHandler() {
        return parent instanceof AbstractConfiguration ? ((AbstractConfiguration) parent).getListDelimiterHandler() : super.getListDelimiterHandler();
    }

    /**
     * Gets the parent configuration for this subset.
     *
     * @return the parent configuration
     */
    public Configuration getParent() {
        return parent;
    }

    /**
     * Gets the key in the parent configuration associated to the specified key in this subset.
     *
     * @param key The key in the subset.
     * @return the key as to be used by the parent
     */
    protected String getParentKey(final String key) {
        if (StringUtils.isEmpty(key)) {
            return prefix;
        }
        return delimiter == null ? prefix + key : prefix + delimiter + key;
    }

    /**
     * Gets the prefix used to select the properties in the parent configuration.
     *
     * @return the prefix used by this subset
     */
    public String getPrefix() {
        return prefix;
    }

    @Override
    protected Object getPropertyInternal(final String key) {
        return parent.getProperty(getParentKey(key));
    }

    /**
     * Initializes the {@code ConfigurationInterpolator} for this sub configuration. This is a standard
     * {@code ConfigurationInterpolator} which also references the {@code ConfigurationInterpolator} of the parent
     * configuration.
     */
    private void initInterpolator() {
        getInterpolator().setParentInterpolator(getParent().getInterpolator());
    }

    @Override
    protected boolean isEmptyInternal() {
        return !getKeysInternal().hasNext();
    }

    /**
     * {@inheritDoc}
     *
     * The subset inherits this feature from its parent if it supports this feature.
     */
    @Override
    public boolean isThrowExceptionOnMissing() {
        if (parent instanceof AbstractConfiguration) {
            return ((AbstractConfiguration) parent).isThrowExceptionOnMissing();
        }
        return super.isThrowExceptionOnMissing();
    }

    /**
     * {@inheritDoc} If the parent configuration extends {@link AbstractConfiguration}, the list delimiter handler is passed
     * to the parent.
     */
    @Override
    public void setListDelimiterHandler(final ListDelimiterHandler listDelimiterHandler) {
        if (parent instanceof AbstractConfiguration) {
            ((AbstractConfiguration) parent).setListDelimiterHandler(listDelimiterHandler);
        } else {
            super.setListDelimiterHandler(listDelimiterHandler);
        }
    }

    /**
     * Sets the prefix used to select the properties in the parent configuration.
     *
     * @param prefix the prefix
     */
    public void setPrefix(final String prefix) {
        this.prefix = prefix;
    }

    /**
     * {@inheritDoc}
     *
     * Change the behavior of the parent configuration if it supports this feature.
     */
    @Override
    public void setThrowExceptionOnMissing(final boolean throwExceptionOnMissing) {
        if (parent instanceof AbstractConfiguration) {
            ((AbstractConfiguration) parent).setThrowExceptionOnMissing(throwExceptionOnMissing);
        } else {
            super.setThrowExceptionOnMissing(throwExceptionOnMissing);
        }
    }

    @Override
    public Configuration subset(final String prefix) {
        return parent.subset(getParentKey(prefix));
    }
}
