package com.tmerclub.cloud.search.canal.support.parser;


import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author throwable
 * @version v1
 * @description
 * @since 2020/9/26 22:39
 */
public class InMemoryParseResultInterceptorManager implements ParseResultInterceptorManager {

    private final ConcurrentMap<Class<?>, List<BaseParseResultInterceptor<?>>> cache = new ConcurrentHashMap<>(16);

    @Autowired
    private ModelTableMetadataManager modelTableMetadataManager;

    public InMemoryParseResultInterceptorManager(ModelTableMetadataManager modelTableMetadataManager) {
        this.modelTableMetadataManager = modelTableMetadataManager;
    }

    public static InMemoryParseResultInterceptorManager of(ModelTableMetadataManager modelTableMetadataManager) {
        return new InMemoryParseResultInterceptorManager(modelTableMetadataManager);
    }

    @Override
    public <T> void registerParseResultInterceptor(BaseParseResultInterceptor<T> parseResultInterceptor) {
        synchronized (cache) {
            Class<T> klass = parseResultInterceptor.getKlass();
            ModelTableMetadata modelTableMetadata = modelTableMetadataManager.load(klass);
            Optional.ofNullable(modelTableMetadata).ifPresent(ignore -> {
                cache.putIfAbsent(parseResultInterceptor.getKlass(), new LinkedList<>());
                cache.get(klass).add(parseResultInterceptor);
            });
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> List<BaseParseResultInterceptor<T>> getParseResultInterceptors(Class<T> klass) {
        return (List<BaseParseResultInterceptor<T>>) (List<?>) cache.getOrDefault(klass, Collections.emptyList());
    }
}
