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

package net.ranides.assira.reflection.impl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.util.Optional;
import java.util.Set;
import net.ranides.assira.reflection.IAnnotations;
import net.ranides.assira.reflection.IArgument;
import net.ranides.assira.reflection.IArguments;
import net.ranides.assira.reflection.IAttribute;
import net.ranides.assira.reflection.IClass;
import net.ranides.assira.reflection.IMethod;
import net.ranides.assira.collection.query.CQueryBuilder;
import net.ranides.assira.reflection.IContext;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class CArgument implements IArgument {
    
    private static final Set<IAttribute> NORMAL = IAttribute.constant(IAttribute.DECLARED, IAttribute.PACKAGE);
    
    private static final Set<IAttribute> GENERIC = IAttribute.constant(IAttribute.DECLARED, IAttribute.PACKAGE, IAttribute.PARAMETERIZED);

    private final IClass<?> type;

    private final String name;

    CArgument(String name, IClass<?> type) {
        this.type = type;
        this.name = name;
    }

    @Override
    public IContext context() {
        return IContext.DEFAULT;
    }
        
    @Override
    public IArguments collect() {
        return FElements.newArguments(AHints.EMPTY, 1, CQueryBuilder.of(this));
    }

    @Override
    public IClass<?> type() {
        return type;
    }

    @Override
    public IMethod parent() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Parameter reflective() {
        throw new UnsupportedOperationException();
    }

    @Override
    public String name() {
        if(null == name) {
            throw new UnsupportedOperationException();
        }
        return name;
    }

    @Override
    public Set<IAttribute> attributes() {
        return type.attributes().contains(IAttribute.PARAMETERIZED) ? GENERIC : NORMAL;
    }

    @Override
    public IAnnotations annotations() {
        return AAnnotations.EMPTY;
    }
    
    @Override
    public <A extends Annotation> Optional<A> annotation(Class<A> type) {
        return annotations().first(type);
    }

    @Override
    public final int hashCode() {
        return this.type().hashCode();
    }

    @Override
    public final boolean equals(Object object) {
        return (object instanceof IArgument) && ((IArgument)object).type().equals(type());
    }
    
}
