package net.northking.cctp.element.core.keyword;

import net.northking.cctp.element.core.annotation.Keywords;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Keyword factory
 *
 * @author fengxiang.zhang
 * @since 1.0
 */
public class KeywordFactory implements IKeywordFactory {

    @Override
    public Map<String, Keyword> createKeywords(Collection<Object> keywordBeanValues) {
        Map<String, Keyword> keywords = new ConcurrentHashMap<>();
        extractKeywords(keywords, keywordBeanValues);
        return keywords;
    }

    /**
     * Extract keywords by registered beans
     *
     * @param keywords
     * @param keywordBeanValues
     */
    protected void extractKeywords(Map<String, Keyword> keywords, Collection<Object> keywordBeanValues) {
        IKeywordExtractor<Keyword> keywordExtractor = createKeywordExtractor();
        for (Object keywordBean : keywordBeanValues) {
            if (!keywordBean.getClass().isAnnotationPresent(Keywords.class)) {
                continue;
            }
            Map<String, Keyword> extractedKeywords = keywordExtractor.extractKeywords(keywordBean);
            addKeywords(keywords, extractedKeywords);
        }
    }

    IKeywordExtractor<Keyword> createKeywordExtractor() {
        return new KeywordExtractor();
    }

    private void addKeywords(Map<String, Keyword> keywords,
                             Map<String, Keyword> extractedKeywords) {
        for (String keywordName : extractedKeywords.keySet()) {
            if (keywords.containsKey(keywordName)) {
                throw new RuntimeException("Two keywords with name '" + keywordName + "' found!");
            }
            keywords.put(keywordName, extractedKeywords.get(keywordName));
        }
    }
}