package org.dynalang.mop.impl.test;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.dynalang.mop.ClassBasedMetaobjectProtocol;
import org.dynalang.mop.CallProtocol;
import org.dynalang.mop.impl.MetaobjectProtocolBase;

public class DummyMetaobjectProtocol1 extends MetaobjectProtocolBase implements ClassBasedMetaobjectProtocol {
    
    public boolean isAuthoritativeForClass(Class clazz) {
        return clazz == DynaObject1.class;
    }
    
    public Object call(Object callable, CallProtocol callProtocol, Map args) {
	return Result.noAuthority; // not callable with named args  
    }

    public Object call(Object callable, CallProtocol callProtocol,
	    Object... args) {
	return isDynaObject1(callable) ? "called1" : Result.noAuthority; 
    }
    public Result delete(Object target, Object propertyId) {
        return isAuthoritative(target, propertyId) ? Result.notDeleteable : Result.noAuthority;
    }

    public Object get(Object target, Object propertyId) {
	return isAuthoritative(target, propertyId) ? "value1" : Result.noAuthority;
    }

    public Boolean has(Object target, Object propertyId) {
	return isAuthoritative(target, propertyId) ? Boolean.TRUE : null;
    }

    private boolean isAuthoritative(Object target, Object propertyId) {
	return isDynaObject1(target) && "prop1".equals(propertyId);
    }

    public Iterator<Entry> properties(Object target) {
	if(isDynaObject1(target)) {
            Map m = new HashMap();
            m.put("prop1", "value1");
            return m.entrySet().iterator();
	}
	else {
	    return Collections.EMPTY_MAP.entrySet().iterator();
	}
    }

    public Result put(Object target, Object propertyId, Object value,
	    CallProtocol callProtocol) {
        return isAuthoritative(target, propertyId) ? Result.notWritable : Result.noAuthority;
    }

    public Object representAs(Object object, Class targetClass) {
	return isDynaObject1(object) && targetClass == String.class ? 
		"value1" : Result.noAuthority;
    }

    private boolean isDynaObject1(Object object) {
	return object instanceof DynaObject1;
    }
}