package com.chushang.common.mongo.listener;

import com.chushang.common.mongo.annotation.MongoDel;
import com.chushang.common.mongo.entity.Garbage;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeDeleteEvent;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author by zhaowenyuan create 2022/7/18 14:06
 *
 * // 当使用此方法删除时, 需注
 * 1. 不能使用 deleteAll 因为其doRemove 时未指定实体类型, 而回调事件时需要实体类型不能为空
 * 2. 直接使用 mongoTemplate.remove 方法删除数据时，必须指定 entityClass
 */
public class MongoEventListener<E> extends AbstractMongoEventListener<E> {

    private final MongoTemplate mongoTemplate;

    public MongoEventListener(MongoTemplate mongoTemplate){
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public void onBeforeDelete(BeforeDeleteEvent<E> event) {
        if (null == event.getType() || CollectionUtils.isEmpty(event.getDocument())){
            return;
        }
        Class<E> eventType = event.getType();
        MongoDel mongoDel = eventType.getAnnotation(MongoDel.class);
        if (null == mongoDel || !mongoDel.logic()) return;
        List<E> es = mongoTemplate.find(new BasicQuery(event.getDocument()), eventType);
        if (!CollectionUtils.isEmpty(es)){
            // 删除之前将数据迁移搭到 garbage 中
            String type = event.getCollectionName();
            LocalDateTime now = LocalDateTime.now();
            List<Garbage> garbageList =
                    es.stream().map(o -> new Garbage(null, type, o, now)).collect(Collectors.toList());
            mongoTemplate.insertAll(garbageList);
        }


    }
}
