/*
 * @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.reflect.Parameter;
import java.util.Set;
import net.ranides.assira.reflection.*;
import net.ranides.assira.collection.query.CQueryBuilder;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class RArgument implements IArgument {

    private final IContext context;
    
    private final IMethod parent;
    
    private final Parameter param;

    RArgument(IContext context, IMethod parent, Parameter param) {
        this.parent = parent;
        this.param = param;
        this.context = context;
    }

    @Override
    public IContext context() {
        return context;
    }

    @Override
    public IArguments collect() {
        return new AArguments(AHints.EMPTY, CQueryBuilder.of(this));
    }

    @Override
    public Parameter reflective() {
        return param;
    }

    @Override
    public IClass type() {
        final IContext c = context();
        return new RFClass(c, c.typeinfo(param.getParameterizedType()), param.getAnnotatedType());
    }

    @Override
    public String name() {
        if(!param.isNamePresent()) {
            throw new UnsupportedOperationException("You have to compile class with -parameters switch");
        }
        return param.getName();
    }

    @Override
    public IMethod parent() {
        return parent;
    }

    @Override
    public Set<IAttribute> attributes() {
        return IAttribute.resolve(param);
    }

    @Override
    public IAnnotations annotations() {
        return new AAnnotations(AHints.EMPTY, CQueryBuilder.fromArray(param.getAnnotations()));
    }

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

    @Override
    public String toString() {
        return type() + " " + param.getName();
    }
    
}
