/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.reflection;

import net.ranides.assira.collection.query.CQuery;
import net.ranides.assira.reflection.impl.AAnnotations;
import net.ranides.assira.reflection.impl.AArguments;
import net.ranides.assira.reflection.impl.AConstructors;
import net.ranides.assira.reflection.impl.FElements;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.function.Predicate;

/**
 * Fluent interface for collection of IConstructor objects
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @param <T> T
 */
public interface IConstructors<T> extends IExecutables<IConstructor<T>> {

    /**
     * Factory: returns collection with each constructor converted to IConstructor
     *
     * @param methods methods
     * @param <T> T
     * @return IConstructors
     */
    @SafeVarargs
    static <T> IConstructors<T> typeinfo(Constructor<T>... methods) {
        return FElements.newConstructors(methods);
    }

    /**
     * Factory: returns empty collection
     *
     * @return collection
     * @param <T> T
     */
    static <T> IConstructors<T> empty() {
        return AConstructors.$empty();
    }

    @Override
    IConstructors<T> require(Predicate<? super IConstructor<T>> predicate);

    @Override
    IConstructors<T> require(IAnnotations annotations);

    @Override
    IConstructors<T> require(Class<? extends Annotation> annotation);

    @Override
    IConstructors<T> require(IAttribute attribute);

    @Override
    IConstructors<T> require(IAttributes attributes);

    @Override
    IConstructors<T> require(String name);

    @Override
    IConstructors<T> require(IClass<?> returns);

    @Override
    IConstructors<T> require(IArguments arguments);

    @Override
    IConstructors<T> require(int arguments);

    @Override
    IConstructors<T> discard(Predicate<? super IConstructor<T>> predicate);

    @Override
    IConstructors<T> discard(IAnnotations annotations);

    @Override
    IConstructors<T> discard(Class<? extends Annotation> annotation);

    @Override
    IConstructors<T> discard(IAttribute attribute);

    @Override
    IConstructors<T> discard(IAttributes attributes);

    @Override
    IConstructors<T> discard(String name);

    @Override
    IConstructors<T> discard(IClass<?> returns);

    @Override
    IConstructors<T> discard(IArguments arguments);

    @Override
    IConstructors<T> discard(int arguments);

    @Override
    IConstructors<T> matches(IClasses arguments);

    @Override
    IConstructors<T> accepts(Object... arguments);

    @Override
    IConstructors<T> accessible();

    /**
     * Returns stream with each constructor mapped to reflective Constructor
     *
     * @return CQuery
     */
    CQuery<Constructor<T>> reflective();

}
