/*
 * 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.bval.jsr303.groups;


import javax.validation.GroupDefinitionException;
import javax.validation.GroupSequence;
import javax.validation.ValidationException;
import javax.validation.groups.Default;
import java.util.*;

/**
 * Description: compute group order, based on the RI behavior as to guarantee
 * compatibility with interpretations of the spec.<br/>
 * Implementation is thread-safe.
 */
public class GroupsComputer {
    /** The default group array used in case any of the validate methods is called without a group. */
    private static final Groups DEFAULT_GROUPS;

    static {
        DEFAULT_GROUPS = new GroupsComputer().computeGroups(Arrays.asList(getDefaultGroupArray()));
    }

    /**
     * Get the default group array.
     * @return <code>{@link Default}.class</code> only
     */
    public static Class<?>[] getDefaultGroupArray() {
        return new Class<?>[] { Default.class };
    }

    /** caching resolved groups in a thread-safe map. */
    private final Map<Class<?>, List<Group>> resolvedSequences = Collections
        .synchronizedMap(new HashMap<Class<?>, List<Group>>());

    /**
     * Compute groups from an array of group classes.
     * @param groups
     * @return {@link Groups}
     */
    public Groups computeGroups(Class<?>[] groups) {
        if (groups == null) {
            throw new IllegalArgumentException("null passed as group");
        }

        // if no groups is specified use the default
        if (groups.length == 0) {
            return DEFAULT_GROUPS;
        }

        return computeGroups(Arrays.asList(groups));
    }

    /**
     * Main compute implementation.
     * @param groups
     * @return {@link Groups}
     */
    protected Groups computeGroups(Collection<Class<?>> groups) {
        if (groups == null || groups.size() == 0) {
            throw new IllegalArgumentException("At least one group has to be specified.");
        }

        for (Class<?> clazz : groups) {
            if (!clazz.isInterface()) {
                throw new ValidationException(
                      "A group has to be an interface. " + clazz.getName() + " is not.");
            }
        }

        Groups chain = new Groups();
        for (Class<?> clazz : groups) {
            GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
            if (anno == null) {
                Group group = new Group(clazz);
                chain.insertGroup(group);
                insertInheritedGroups(clazz, chain);
            } else {
                insertSequence(clazz, anno, chain);
            }
        }

        return chain;
    }

    private void insertInheritedGroups(Class<?> clazz, Groups chain) {
        for (Class<?> extendedInterface : clazz.getInterfaces()) {
            Group group = new Group(extendedInterface);
            chain.insertGroup(group);
            insertInheritedGroups(extendedInterface, chain);
        }
    }

    private void insertSequence(Class<?> clazz, GroupSequence anno, Groups chain) {
        List<Group> sequence;
        if (resolvedSequences.containsKey(clazz)) {
            sequence = resolvedSequences.get(clazz);
        } else {
            sequence = resolveSequence(clazz, anno, new HashSet<Class<?>>());
        }
        chain.insertSequence(sequence);
    }

    private List<Group> resolveSequence(Class<?> group, GroupSequence sequenceAnnotation,
                                        Set<Class<?>> processedSequences) {
        if (processedSequences.contains(group)) {
            throw new GroupDefinitionException("Cyclic dependency in groups definition");
        } else {
            processedSequences.add(group);
        }
        List<Group> resolvedGroupSequence = new LinkedList<Group>();
        Class<?>[] sequenceArray = sequenceAnnotation.value();
        for (Class<?> clazz : sequenceArray) {
            GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
            if (anno == null) {
                resolvedGroupSequence.add(new Group(clazz)); // group part of sequence
            } else {
                List<Group> tmpSequence =
                      resolveSequence(clazz, anno, processedSequences);  // recursion!
                resolvedGroupSequence.addAll(tmpSequence);
            }
        }
        resolvedSequences.put(group, resolvedGroupSequence);
        return resolvedGroupSequence;
    }
}
