/*
 * 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.sis.metadata.iso;

import java.util.Arrays;
import java.util.List;
import java.util.Iterator;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import org.apache.sis.internal.metadata.legacy.LegacyPropertyAdapter;


/**
 * A specialization of {@link LegacyPropertyAdapter} which will try to merge the
 * {@code "hierarchyLevel"} and {@code "hierarchyLevelName"} properties in the same
 * {@link DefaultMetadataScope} instance.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.5
 * @since   0.5
 * @module
 */
abstract class MetadataScopeAdapter<L> extends LegacyPropertyAdapter<L,DefaultMetadataScope> {
    /**
     * @param scopes Value of {@link DefaultMetadata#getMetadataScopes()}.
     */
    MetadataScopeAdapter(final Collection<DefaultMetadataScope> scopes) {
        super(scopes);
    }

    /**
     * Invoked (indirectly) by JAXB when adding a new scope code or scope name. This implementation searches
     * for an existing {@code MetadataScope} instance with a free slot for the new value before to create a
     * new {@link DefaultMetadataScope} instance.
     */
    @Override
    public boolean add(final L newValue) {
        int n = 0;
        final Iterator<DefaultMetadataScope> it = elements.iterator();
        while (it.hasNext()) {
            DefaultMetadataScope scope = it.next();
            if (unwrap(scope) != null) {
                n++;
                continue;
            }
            /*
             * We found a free slot. If the slot is a metadata that we can modify (which is the usual case),
             * we will be allowed to update that instance directly - no change needed in the backing collection.
             * But if the metadata is not modifiable, then we will need to clone it and replaces the element in
             * the collection.
             */
            if (scope.state() == DefaultMetadataScope.State.FINAL) {
                scope = new DefaultMetadataScope(scope);
                if (elements instanceof List<?>) {
                    ((List<DefaultMetadataScope>) elements).set(n, scope);
                } else {
                    /*
                     * Not a list. Delete all the remaining parts, substitute the value
                     * and reinsert everything in the same order.
                     */
                    final DefaultMetadataScope[] remaining = new DefaultMetadataScope[elements.size() - n];
                    remaining[0] = scope;
                    n = 1;
                    it.remove();
                    while (it.hasNext()) {
                        remaining[n++] = it.next();
                        it.remove();
                    }
                    if (n != remaining.length) { // Paranoiac check.
                        throw new ConcurrentModificationException();
                    }
                    elements.addAll(Arrays.asList(remaining));
                }
            }
            return update(scope, newValue);
        }
        return super.add(newValue);
    }
}
