/**
 * 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.cxf.phase;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.SortedSet;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.cxf.common.util.ModCountCopyOnWriteArrayList;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.message.Message;

/**
 * The PhaseChainCache provides default interceptor chains for SOAP requests
 * and responses, both from the client and web service side.  The list of
 * phases supplied in the get() methods of this class are defined by default
 * within org.apache.cxf.phase.PhaseManagerImpl.  For an example of this class
 * in use, check the sourcecode of org.apache.cxf.endpoint.ClientImpl.
 */
public final class PhaseChainCache {
    AtomicReference<ChainHolder> lastData = new AtomicReference<>();

    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
                                     List<Interceptor<? extends Message>> p1) {
        return getChain(lastData, phaseList, p1);
    }

    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
                                     List<Interceptor<? extends Message>> p1,
                                     List<Interceptor<? extends Message>> p2) {
        return getChain(lastData, phaseList, p1, p2);
    }
    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
                                     List<Interceptor<? extends Message>> p1,
                                     List<Interceptor<? extends Message>> p2,
                                     List<Interceptor<? extends Message>> p3) {
        return getChain(lastData, phaseList, p1, p2, p3);
    }
    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
                                     List<Interceptor<? extends Message>> p1,
                                     List<Interceptor<? extends Message>> p2,
                                     List<Interceptor<? extends Message>> p3,
                                     List<Interceptor<? extends Message>> p4) {
        return getChain(lastData, phaseList, p1, p2, p3, p4);
    }
    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
                                     List<Interceptor<? extends Message>> p1,
                                     List<Interceptor<? extends Message>> p2,
                                     List<Interceptor<? extends Message>> p3,
                                     List<Interceptor<? extends Message>> p4,
                                     List<Interceptor<? extends Message>> p5) {
        return getChain(lastData, phaseList, p1, p2, p3, p4, p5);
    }

    @SafeVarargs
    static PhaseInterceptorChain getChain(AtomicReference<ChainHolder> lastData,
                                          SortedSet<Phase> phaseList,
                                         List<Interceptor<? extends Message>> ... providers) {
        ChainHolder last = lastData.get();

        if (last == null
            || !last.matches(providers)) {

            PhaseInterceptorChain chain = new PhaseInterceptorChain(phaseList);
            List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> copy
                = new ArrayList<>(providers.length);
            for (List<Interceptor<? extends Message>> p : providers) {
                copy.add(new ModCountCopyOnWriteArrayList<>(p));
                chain.add(p);
            }
            last = new ChainHolder(chain, copy);
            lastData.set(last);
        }


        return last.chain.cloneChain();
    }

    private static class ChainHolder {
        List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> lists;
        PhaseInterceptorChain chain;

        ChainHolder(PhaseInterceptorChain c,
                    List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> l) {
            lists = l;
            chain = c;
        }

        @SafeVarargs
        final boolean matches(List<Interceptor<? extends Message>> ... providers) {
            if (lists.size() == providers.length) {
                for (int x = 0; x < providers.length; x++) {
                    if (lists.get(x).size() != providers[x].size()) {
                        return false;
                    }

                    if (providers[x].getClass() == ModCountCopyOnWriteArrayList.class) {
                        if (((ModCountCopyOnWriteArrayList<?>)providers[x]).getModCount()
                            != lists.get(x).getModCount()) {
                            return false;
                        }
                    } else {
                        ListIterator<Interceptor<? extends Message>> i1 = lists.get(x).listIterator();
                        ListIterator<Interceptor<? extends Message>> i2 = providers[x].listIterator();

                        while (i1.hasNext()) {
                            if (i1.next() != i2.next()) {
                                return false;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }
    }
}
