package org.iri_research.renkan.coweb.event;

import java.io.Serializable;
import java.util.Map;

import javax.inject.Inject;

import org.iri_research.renkan.RenkanException;
import org.iri_research.renkan.models.IRenkanModel;
import org.iri_research.renkan.models.Project;
import org.iri_research.renkan.models.ProjectSync;
import org.iri_research.renkan.repositories.ProjectSyncsRepository;
import org.iri_research.renkan.repositories.ProjectsRepository;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractBaseSyncEventManager<T extends IRenkanModel<ID>, ID extends Serializable>
        implements ISyncEventManager<T, ID> {

    private final Logger logger = LoggerFactory
            .getLogger(AbstractBaseSyncEventManager.class);

    @Inject
    private ProjectsRepository projectsRepository;

    @Inject
    private ProjectSyncsRepository projectSyncsRepository;

    @Override
    public ProjectsRepository getProjectsRepository() {
        return this.projectsRepository;
    }

    @Override
    public void dispatchEvent(String clientId, Map<String, Object> data) {

        this.saveSyncEvent(data);

        String eventType = (String) data.get("type");

        if ("null".equalsIgnoreCase(eventType)) {
            this.nullOperation(null, data);
        } else if ("update".equalsIgnoreCase(eventType)) {
            this.update(clientId, data);
        } else if ("insert".equalsIgnoreCase(eventType)) {
            this.insert(clientId, data);
        } else if ("delete".equalsIgnoreCase(eventType)) {
            this.delete(clientId, data);
        } else {
            logger.warn(String.format("dispatchEvent : eventType unknown %s",
                    eventType));
        }
    }

    private void saveSyncEvent(Map<String, Object> data) {

        String project_id = null;
        String user_id = null;

        @SuppressWarnings("unchecked")
        Map<String, Object> values = (Map<String, Object>) data.get("value");

        if (values != null) {
            project_id = (String) values.get("_project_id");
        }

        if (project_id == null || "".equals(project_id)) {
            logger.warn("saveSyncEvent : project id is null. Can not save sync event");
            return;
        }

        Project p = this.projectsRepository.findOne(project_id);

        if (p == null) {
            logger.warn("saveSyncEvent : project not found. Can not save sync event");
            return;
        }

        p.setUpdated(new DateTime());
        this.projectsRepository.save(p);

        user_id = (String) values.get("_user_id");

        if (user_id == null) {
            logger.warn("saveSyncEvent : No user id");
        }

        try {
            ProjectSync ps = this.projectSyncsRepository.getProjectSync(
                    data.toString(), p, user_id);
            this.projectSyncsRepository.save(ps);
        } catch (RenkanException e) {
            logger.warn(
                    "saveSyncEvent : Error when getting Projectr syn object", e);
        }

    }

}
