/*
 * 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.myfaces.extensions.validator.core.metadata.transformer;

import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;
import org.apache.myfaces.extensions.validator.core.mapper.SubMapperAwareNameMapper;
import org.apache.myfaces.extensions.validator.core.Nested;
import org.apache.myfaces.extensions.validator.internal.UsageCategory;
import org.apache.myfaces.extensions.validator.internal.UsageInformation;

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;


/**
 * @since x.x.3
 */
@UsageInformation({UsageCategory.INTERNAL})
class SortedNameMapperList<T extends NameMapper> extends CopyOnWriteArrayList<T>
{
    private static final long serialVersionUID = 1502156999599962365L;

    private List<T> wrapped;
    private List<T> globalSubNameMapperList;

    SortedNameMapperList(List<T> wrapped, List<T> subNameMapperList)
    {
        this.wrapped = wrapped;
        this.globalSubNameMapperList = subNameMapperList;
    }

    public boolean add(T t)
    {
        if (t != null && t.getClass().isAnnotationPresent(Nested.class))
        {
            return addSubNameMapper(t);
        }
        else
        {
            boolean result = wrapped.add(t);

            sortWrappedList();
            return result;
        }
    }

    private void sortWrappedList()
    {
        List<T> sortableList = new ArrayList<T>(wrapped);
        Collections.sort(sortableList, new Comparator<T>()
        {
            public int compare(T nm1, T nm2)
            {
                if (nm1 instanceof SubMapperAwareNameMapper && nm2 instanceof SubMapperAwareNameMapper)
                {
                    return 0;
                }
                return nm1 instanceof SubMapperAwareNameMapper ? 1 : -1;
            }
        });
        wrapped.clear();
        wrapped.addAll(sortableList);
    }

    @SuppressWarnings({"unchecked"})
    private boolean addSubNameMapper(T subNameMapper)
    {
        boolean result = false;
        for (NameMapper nameMapper : this.wrapped)
        {
            if (nameMapper instanceof SubMapperAwareNameMapper)
            {
                ((SubMapperAwareNameMapper) nameMapper).addNameMapper(subNameMapper);
                result = true;
            }
        }

        tryToAddMapperAsGlobalSubNameMapper(subNameMapper);
        return result;
    }

    private void tryToAddMapperAsGlobalSubNameMapper(T subNameMapper)
    {
        if(!this.globalSubNameMapperList.contains(subNameMapper))
        {
            this.globalSubNameMapperList.add(subNameMapper);
        }
    }

    /*
     * generated
     */
    public int size()
    {
        return wrapped.size();
    }

    public boolean isEmpty()
    {
        return wrapped.isEmpty();
    }

    public boolean contains(Object o)
    {
        return wrapped.contains(o);
    }

    public Iterator<T> iterator()
    {
        return wrapped.iterator();
    }

    public Object[] toArray()
    {
        return wrapped.toArray();
    }

    @SuppressWarnings({"SuspiciousToArrayCall"})
    public <T> T[] toArray(T[] a)
    {
        return wrapped.toArray(a);
    }

    public boolean remove(Object o)
    {
        return wrapped.remove(o);
    }

    public boolean containsAll(Collection<?> c)
    {
        return wrapped.containsAll(c);
    }

    public boolean addAll(Collection<? extends T> c)
    {
        return wrapped.addAll(c);
    }

    public boolean addAll(int index, Collection<? extends T> c)
    {
        return wrapped.addAll(index, c);
    }

    public boolean removeAll(Collection<?> c)
    {
        return wrapped.removeAll(c);
    }

    public boolean retainAll(Collection<?> c)
    {
        return wrapped.retainAll(c);
    }

    public void clear()
    {
        wrapped.clear();
    }

    public T get(int index)
    {
        return wrapped.get(index);
    }

    public T set(int index, T element)
    {
        return wrapped.set(index, element);
    }

    public void add(int index, T element)
    {
        wrapped.add(index, element);
    }

    public T remove(int index)
    {
        return wrapped.remove(index);
    }

    public int indexOf(Object o)
    {
        return wrapped.indexOf(o);
    }

    public int lastIndexOf(Object o)
    {
        return wrapped.lastIndexOf(o);
    }

    public ListIterator<T> listIterator()
    {
        return wrapped.listIterator();
    }

    public ListIterator<T> listIterator(int index)
    {
        return wrapped.listIterator(index);
    }

    public List<T> subList(int fromIndex, int toIndex)
    {
        return wrapped.subList(fromIndex, toIndex);
    }
}