package be.iminds.ilabt.jfed.rspec.model;

import be.iminds.ilabt.jfed.rspec.model.impl.BasicRspecFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * User: twalcari
 * Date: 8/26/2014
 * Time: 14:46
 */
@SuppressWarnings("unchecked")
public class RspecFactoryFactory {
    private static final Logger LOG = LoggerFactory.getLogger(RspecFactoryFactory.class);
    private static final RspecFactory fxRspecFactory;


    static {
        RspecFactory factory = null;
        //try to find the FXRspecFactory in the classpath
        try {
            Class<RspecFactory> fxRspecFactoryClazz =
                    (Class<RspecFactory>) Class.forName("be.iminds.ilabt.jfed.rspec.model.javafx_impl.FXRspecFactory");
            Method m = fxRspecFactoryClazz.getDeclaredMethod("getInstance");
            factory = (RspecFactory) m.invoke(null);

        } catch (ClassNotFoundException e) {
            LOG.debug("Could not find FXRspecFactory. rspec-fx probably isn't loaded. (ClassNotFoundException not logged)"/*, e*/);
        } catch (NoSuchMethodException e) {
            LOG.error("Could not find FXRspecFactory#getInstance.", e);
        } catch (InvocationTargetException | IllegalAccessException e) {
            LOG.error("Error while creating FXRspecFactory", e);
        } catch (AssertionError e) {
            LOG.error("AssertionError while creating FXRspecFactory", e);
        } catch (Exception t) {
            //This catch-all is needed: otherwise, any failure here becomes a hard to trace failure during class loading, such as:
            //  java.lang.NoClassDefFoundError: Could not initialize class RspecFactoryFactory
            //
            // This happened to me (wvdemeer) due to "wrong bytecode", as FXRspecFactory is java8, and I loaded RspecFactoryFactory from java 7, while the rspex-fx module was available.
            // (and this error then occured womewhere deep inside log4j which made it harder to find out what went wrong.)
            LOG.error("Another fatal error while creating staticly FXRspecFactory: "+t.getMessage(), t);
        }
        fxRspecFactory = factory;
    }


    private RspecFactoryFactory() {
    }

    public static RspecFactory getRspecFactoryInstance(ModelRspecType modelRspecType) {
        switch (modelRspecType) {
            case BASIC:
                return BasicRspecFactory.getInstance();
            case FX:
                return fxRspecFactory;
            default:
                throw new RuntimeException("Unexpected ModelRspecType " + modelRspecType);
        }
    }

}
