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

package net.ranides.assira.reflection;

import java.util.Map;
import java.util.Optional;

import net.ranides.assira.reflection.impl.bean.FBeanModel;

/**
 * 
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public interface BeanModel {
    
    static BeanModel typeinfo(Class<?> type) {
        return typeinfo(IClass.typeinfo(type));
    }
    
    static BeanModel typeinfo(IClass<?> type) {
        return FBeanModel.resolve(type);
    }
    
    static BeanModel typefor(Object object) {
        return typeinfo(IClass.typefor(object));
    }

    // java.beans.Introspector jest w praktyce totalnie przestarzałe - nie wypuszczamy tego wcale
    // MOŻE wewnętrznie używajmy... ale tylko MOŻE. Ręczne zaimplementowanie wchodzi w grę, bo i tak
    // musimy porobić hacki na Introspektora, np żeby obsługiwać:
    //      - overloaded methods
    //      - overloaded setters (NIE obsługujemy obecnie!)
    //      - indexed properties: Type[] oraz List<Type>
    //      - generic types
    
    IClass<?> type();
    
    Optional<BeanMethod> method(String name);
    
    Map<String, BeanMethod> methods();

    Optional<BeanProperty> property(String name);
    
    Map<String, BeanProperty> properties();
    
    Map<String, Object> values(Object that);
    
    Object construct();
    
    Object construct(Map<String, Object> values);
    
    Object clone(Object that);
    
}
