package com.bocloud.ims.service.config;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.utils.JSONTools;

/**
 * 系统配置信息缓存通用类
 * 
 * @author wangyu
 * @version 1.0
 * @since 2017年8月22日
 * 
 */
public class Configuration {

	private static Logger logger = LoggerFactory.getLogger(Configuration.class);
	private Map<String, String> configMap;
	static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
	static Lock readLock = rwLock.readLock();
	static Lock writeLock = rwLock.writeLock();

	/*
	 * 
	 */
	private Configuration() {
		super();
		if (null != ConfigurationContainer.instance) {// 防止利用反射机制实现多个对象的漏洞
			throw new RuntimeException("System Configuration遭受反射攻击！");
		}
		configMap = new ConcurrentHashMap<>();
	}

	/**
	 * 获取配置实例方法
	 * 
	 * @return
	 */
	public static Configuration getInstance() {
		return ConfigurationContainer.instance;
	}

	/**
	 * 更新整体配置
	 * 
	 * @param data
	 */
	public void update(String data) {
		writeLock.lock();
		try {
			if (StringUtils.isEmpty(data)) {
				return;
			}
			processNull();
			BocloudResult<JSONObject> result = JSONTools.isJSON(data);
			if (result.isFailed()) {
				logger.error("Update system config error: 传入参数格式化错误！");
				return;
			}
			JSONObject jsonObject = result.getData();
			configMap.keySet().removeIf(s -> !jsonObject.containsKey(s));
			Set<String> keys = jsonObject.keySet();
			for (String key : keys) {
				configMap.put(key, jsonObject.getString(key));
			}
		} catch (Exception e) {
			logger.error("update system config error:", e);
		} finally {
			writeLock.unlock();
		}
	}

	/**
	 * 获取系统配置
	 * 
	 * @param key
	 * @return
	 */
	public String getConfig(String key) {
		readLock.lock();
		try {
			processNull();
			return configMap.get(key);
		} catch (Exception e) {
			logger.error("get system config error:", e);
			return null;
		} finally {
			readLock.unlock();
		}
	}

	/**
	 * 更新指定key的系统配置
	 * 
	 * @param key
	 * @param data
	 */
	public void update(String key, String value) {
		processNull();
		if (StringUtils.isEmpty(key)) {
			return;
		}
		writeLock.lock();
		try {
			configMap.put(key, value);
		} catch (Exception e) {
			logger.error("update key【{}】 system config exception ", key, e);
		} finally {
			writeLock.unlock();
		}
	}

	private void processNull() {
		if (null == configMap) {
			configMap = new ConcurrentHashMap<>();
		}
	}

	private static class ConfigurationContainer {
		private static final Configuration instance = new Configuration();
	}
}
