/*
 * @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.AConstructors;
import net.ranides.assira.reflection.impl.AMethods;
import net.ranides.assira.reflection.impl.FElements;

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

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

    /**
     * Factory: returns collection with each method converted to IMethod
     *
     * @param methods methods
     * @return IMethods
     */
    static IMethods typeinfo(Method... methods) {
        return FElements.newMethods(methods);
    }

    /**
     * Factory: returns empty collection
     *
     * @return collection
     */
    static IMethods empty() {
        return AMethods.$empty();
    }

    @Override
    IMethods require(Predicate<? super IMethod> predicate);

    @Override
    IMethods require(IAnnotations annotations);

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

    @Override
    IMethods require(IAttribute attribute);

    @Override
    IMethods require(IAttributes attributes);

    @Override
    IMethods require(String name);

    @Override
    IMethods require(IClass<?> returns);

    @Override
    IMethods require(IArguments arguments);

    @Override
    IMethods require(int arguments);

    @Override
    IMethods discard(Predicate<? super IMethod> predicate);

    @Override
    IMethods discard(IAnnotations annotations);

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

    @Override
    IMethods discard(IAttribute attribute);

    @Override
    IMethods discard(IAttributes attributes);

    @Override
    IMethods discard(String name);

    @Override
    IMethods discard(IClass<?> returns);

    @Override
    IMethods discard(IArguments arguments);

    @Override
    IMethods discard(int arguments);

    @Override
    IMethods matches(IClasses arguments);

    @Override
    IMethods accepts(Object... arguments);

    @Override
    IMethods accessible();

    /**
     * Returns stream with each method mapped to reflective Method
     *
     * @return CQuery
     */
    CQuery<Method> reflective();

}
