package com.bughz.forum.system.config;//包路径

import com.bughz.forum.common.model.MessagesLang;//数据库表对应的实体
import com.bughz.forum.common.service.MessagesLangService;//查询数据库的服务类
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author bughz
 * @date 2019/10/17
 * describe: 注意继承的类和实现的接口
 */
@Service("messageSource")
public class MessageResource extends AbstractMessageSource implements ResourceLoaderAware {

    @SuppressWarnings("unused")
    private ResourceLoader resourceLoader;

    @Autowired
    private MessagesLangService messagesLangService;

    /**
     * Map切分字符
     */
    private static final Map<String, Map<String, String>> LOCAL_CACHE = new ConcurrentHashMap<>(256);

    /**
     * 启动项目执行reload方法
     */
    @PostConstruct
    public void init() {
        reload();
    }
    /**
     * 该方法为了刷新缓存中的语言,每次修改了数据库后记得调用一下
     */
    public void reload() {
        LOCAL_CACHE.clear();
        LOCAL_CACHE.putAll(loadTexts());
        System.out.println("");
    }


    /**
     *
     * 描述:TODO
     * 加载数据
     * @return
     */
    public Map<String, Map<String, String>> loadTexts() {
        List<MessagesLang> list = messagesLangService.findAll();
        if (list.size()>0) {
            //因为我只有中文和英文,涉及到其他语言,只需要添加列  和  在这里添加集合即可
            final Map<String, String> zhCnMessageResources = new HashMap<>(list.size());
            final Map<String, String> enUsMessageResources = new HashMap<>(list.size());
            for (MessagesLang ml : list) {
                String name = ml.getKey();
                String zhText = ml.getZhCN();
                String enText = ml.getEnUS();
                zhCnMessageResources.put(name, zhText);
                enUsMessageResources.put(name, enText);
            }
            LOCAL_CACHE.put("zh", zhCnMessageResources);
            LOCAL_CACHE.put("en", enUsMessageResources);
        }
        return MapUtils.EMPTY_SORTED_MAP;
    }

    /**
     * 从缓存中取出国际化配置对应的数据 或者从父级获取
     * 用于java后台从国际化查询内容
     * @param code
     * @param locale
     * @return
     */
    public String getSourceFromCache(String code, Locale locale) {
        String language = locale.getLanguage();
        Map<String, String> props = LOCAL_CACHE.get(language);
        if (null != props && props.containsKey(code)) {
            return props.get(code);
        } else {
            try {
                if (null != this.getParentMessageSource()) {
                    return this.getParentMessageSource().getMessage(code, null, locale);
                }
            } catch (Exception ex) {
                logger.error(ex.getMessage(), ex);
            }
            return code;
        }
    }

    // 下面三个重写的方法是比较重要的
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = (resourceLoader == null ? new DefaultResourceLoader() : resourceLoader);
    }

    @Override
    protected MessageFormat resolveCode(String code, Locale locale) {
        String msg = getSourceFromCache(code, locale);
        MessageFormat messageFormat = new MessageFormat(msg, locale);
        return messageFormat;
    }

    @Override
    protected String resolveCodeWithoutArguments(String code, Locale locale) {
        return getSourceFromCache(code, locale);
    }

}