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

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Set;
import java.util.function.Predicate;
import net.ranides.assira.collection.query.CQuery;
import net.ranides.assira.reflection.impl.FElements;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
@SuppressWarnings("PMD.TooManyDifferentMethods")
public interface IClasses extends IElements<IClass<?>> {
    
    IClasses EMPTY = IContext.DEFAULT.typesinfo();
	
	/**
     * Collect information using java.reflection API
     * @param type
     * @return 
     */
    static IClasses typeinfo(Type... types) {
        return IContext.DEFAULT.typesinfo(types);
    }
    
    static IClasses typeinfo(IClass<?>... types) {
        return FElements.newClasses(types);
    }
    
    static IClasses typefor(Object... objects) {
        return IContext.DEFAULT.typesfor(objects);
    }
    
    IClasses require(Predicate<? super IClass<?>> predicate);
    
    IClasses require(IAnnotations annotations);
    
    IClasses require(Class<? extends Annotation> annotation);
    
    IClasses require(IAttribute attribute);
    
    IClasses require(Set<IAttribute> attributes);
    
    IClasses require(IMethod method);
    
    IClasses discard(Predicate<? super IClass<?>> predicate);
    
    IClasses discard(IAnnotations annotations);
    
    IClasses discard(Class<? extends Annotation> annotation);
    
    IClasses discard(IAttribute attribute);
    
    IClasses discard(Set<IAttribute> attributes);
    
    IClasses discard(IMethod method);
    
    // deep scan
    
    IFields fields();
    
    IMethods constructors();
    
    IMethods methods();
    
    @Override
    IClasses parent();
    
    IClasses parents();
    
    IClasses interfaces();
    
    IClasses outer();
    
    IClasses inner();
    
    CQuery<Type> reflective();
    
    CQuery<Class<?>> raw();
	        
	// some predicates
	
	boolean isSuper(IClasses types);

	boolean isSubclass(IClasses types);
	
    boolean isInstance(Object... values);

            
}
