package org.wisdom.jcrom.runtime;

import com.dooapp.cloud.common.model.AbstractEntity;
import org.jcrom.Jcrom;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wisdom.api.model.Crud;
import org.wisdom.api.model.Repository;
import org.wisdom.jcrom.conf.WJcromConf;
import org.wisdom.jcrom.crud.CrudFactory;
import org.wisdom.jcrom.crud.JcromCrud;

import javax.jcr.RepositoryException;
import javax.jcr.RepositoryFactory;
import javax.jcr.Session;
import java.util.*;

/**
 * Created by antoine on 14/07/2014.
 */
public class JcrRepository implements Repository<javax.jcr.Repository> {

    private Logger logger = LoggerFactory.getLogger(JcromCrudProvider.class);

    private final javax.jcr.Repository repository;

    private final WJcromConf conf;

    private final Jcrom jcrom;

    private final Session session;

    private Collection<ServiceRegistration> registrations = new ArrayList<>();
    private Collection<JcromCrud<?, ?>> crudServices = new ArrayList<>();
    private Map<Class, CrudFactory> crudMapFactory = new HashMap<>();


    public JcrRepository(WJcromConf conf, RepositoryFactory repositoryFactory) throws RepositoryException {
        Map<String, String> parameters = new HashMap<String, String>();
        Thread.currentThread().setContextClassLoader(repositoryFactory.getClass().getClassLoader());
        logger.info("Loading JCR repository using " + repositoryFactory);
        this.repository = repositoryFactory.getRepository(parameters);
        this.jcrom = new Jcrom();
        this.conf = conf;
        addCrudFactory();
        Thread.currentThread().setContextClassLoader(JcrRepository.class.getClassLoader());
        this.session = repository.login();
    }

    public WJcromConf getConf() {
        return conf;
    }

    protected void addCrudFactory() {
    }

    protected void addCrudService(Class entity) throws RepositoryException {
        jcrom.map(entity);
        JcromCrudService<? extends AbstractEntity> jcromCrudService;
        if (crudMapFactory.containsKey(entity)) {
            jcromCrudService = crudMapFactory.get(entity).createCrud(this);
        } else {
            jcromCrudService = new JcromCrudService<AbstractEntity>(this, entity);
        }
        crudServices.add(jcromCrudService);
    }

    protected void registerAllCrud(BundleContext context) {
        for (JcromCrud crud : crudServices) {
            Dictionary prop = conf.toDico();
            prop.put(Crud.ENTITY_CLASS_PROPERTY, crud.getEntityClass());
            prop.put(Crud.ENTITY_CLASSNAME_PROPERTY, crud.getEntityClass().getName());
            registrations.add(context.registerService(new String[]{Crud.class.getName(), JcromCrud.class.getName(), crud.getClass().getName()}, crud, prop));
        }
    }

    protected void destroy() {
        for (ServiceRegistration reg : registrations) {
            reg.unregister();
        }
        registrations.clear();
        crudServices.clear();
        session.logout();
    }

    public javax.jcr.Repository getRepository() {
        return repository;
    }

    public Jcrom getJcrom() {
        return jcrom;
    }

    public Session getSession() {
        return session;
    }

    @Override
    public Collection<Crud<?, ?>> getCrudServices() {
        return (Collection) crudServices;
    }


    @Override
    public String getName() {
        return repository.toString();
    }

    @Override
    public String getType() {
        return "jcr-repository";
    }

    @Override
    public Class<javax.jcr.Repository> getRepositoryClass() {
        return javax.jcr.Repository.class;
    }

    @Override
    public javax.jcr.Repository get() {
        return repository;
    }

    public Map<Class, CrudFactory> getCrudMapFactory() {
        return crudMapFactory;
    }
}

@@ -369,50 +369,8 @@
 nf;%0A
-import org.wisdom.jcrom.crud.CrudFactory;%0A
 impo
@@ -405,16 +405,16 @@
 omCrud;%0A
+
 %0Aimport 
@@ -1038,78 +1038,8 @@
 ();%0A
-    private Map%3CClass, CrudFactory%3E crudMapFactory = new HashMap%3C%3E();%0A
 %0A%0A  
@@ -1974,155 +1974,8 @@
 ce;%0A
-        if (crudMapFactory.containsKey(entity)) %7B%0A            jcromCrudService = crudMapFactory.get(entity).createCrud(this);%0A        %7D else %7B%0A    
     
@@ -2049,26 +2049,16 @@
 ntity);%0A
-        %7D%0A
         
@@ -3482,24 +3482,24 @@
 ory get() %7B%0A
+
         retu
@@ -3522,102 +3522,7 @@
    %7D
-%0A%0A    public Map%3CClass, CrudFactory%3E getCrudMapFactory() %7B%0A        return crudMapFactory;%0A    %7D
 %0A%7D%0A

remove map factory