package com.bcxin.Infrastructures.hibernates;

import com.bcxin.Infrastructures.DataPersistentInterceptor;
import com.bcxin.Infrastructures.TenantContext;
import com.bcxin.Infrastructures.TenantUserContext;
import com.bcxin.Infrastructures.entities.OpEntityAbstract;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;

@Component
/**
 * Hibernate 拦截, 执行操作者的拦截
 */
public class DataInterceptor extends EmptyInterceptor {

    private Collection<DataPersistentInterceptor> getPersistentInterceptors() {
        return TenantContext.getInstance().resolveAll(DataPersistentInterceptor.class);
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
        Collection<DataPersistentInterceptor> persistentInterceptors = this.getPersistentInterceptors();
        for (DataPersistentInterceptor interceptor : persistentInterceptors) {
            interceptor.before(entity, id, currentState, previousState, propertyNames);
        }

        return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types);
    }

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        executeBeforePersistent(entity, id, propertyNames);

        return super.onSave(entity, id, state, propertyNames, types);
    }

    @Override
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        //System.err.println("DataInterceptor.onLoad");
        return super.onLoad(entity, id, state, propertyNames, types);
    }

    protected void executeBeforePersistent(Object entity, Serializable id, String[] propertyNames)
    {
        TenantUserContext.UserModel userModel = TenantContext.getInstance().getUserContext().get();
        if (userModel != null) {
            if (entity instanceof OpEntityAbstract) {
                OpEntityAbstract opEntity = (OpEntityAbstract) entity;
                if (opEntity.getCreator() == null) {
                    opEntity.assignCreator(userModel.getId(), userModel.getName());
                }
                opEntity.assignModifier(userModel.getId(), userModel.getName());
            }
        }
    }
}
