package com.dianping.cat.consumer.transaction;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.unidal.dal.jdbc.DalException;
import org.unidal.dal.jdbc.DalNotFoundException;
import org.unidal.lookup.annotation.Inject;
import org.xml.sax.SAXException;

import com.dianping.cat.Cat;
import com.dianping.cat.config.content.ContentFetcher;
import com.dianping.cat.consumer.transaction.config.entity.AllTransactionConfig;
import com.dianping.cat.consumer.transaction.config.entity.Name;
import com.dianping.cat.consumer.transaction.config.entity.Type;
import com.dianping.cat.consumer.transaction.config.transform.DefaultSaxParser;
import com.dianping.cat.core.config.Config;
import com.dianping.cat.core.config.ConfigDao;
import com.dianping.cat.core.config.ConfigEntity;

public class AllTransactionConfigManager implements Initializable, LogEnabled {

	@Inject
	private ConfigDao m_configDao;

	@Inject
	private ContentFetcher m_fetcher;

	private int m_configId;

	private AllTransactionConfig m_config;

	private Logger m_logger;

	private long m_modifyTime;

	private static final String CONFIG_NAME = "all-transaction-config";

	@Override
	public void enableLogging(Logger logger) {
		m_logger = logger;
	}

	public AllTransactionConfig getConfig() {
		return m_config;
   }

	@Override
	public void initialize() throws InitializationException {
		try {
			Config config = m_configDao.findByName(CONFIG_NAME, ConfigEntity.READSET_FULL);
			String content = config.getContent();

			m_configId = config.getId();
			m_config = DefaultSaxParser.parse(content);
			m_modifyTime = config.getModifyDate().getTime();
		} catch (DalNotFoundException e) {
			try {
				String content = m_fetcher.getConfigContent(CONFIG_NAME);
				Config config = m_configDao.createLocal();
				Date now = new Date();

				config.setName(CONFIG_NAME);
				config.setContent(content);
				config.setModifyDate(now);
				m_configDao.insert(config);

				m_configId = config.getId();
				m_config = DefaultSaxParser.parse(content);
				m_modifyTime = now.getTime();
			} catch (Exception ex) {
				Cat.logError(ex);
			}
		} catch (Exception e) {
			Cat.logError(e);
		}
		if (m_config == null) {
			m_config = new AllTransactionConfig();
		}
	}

	public boolean insert(String xml) {
		try {
			m_config = DefaultSaxParser.parse(xml);
			boolean result = storeConfig();

			return result;
		} catch (Exception e) {
			Cat.logError(e);
			m_logger.error(e.getMessage(), e);
			return false;
		}
	}

	public void refreshConfig() throws DalException, SAXException, IOException {
		Config config = m_configDao.findByName(CONFIG_NAME, ConfigEntity.READSET_FULL);
		long modifyTime = config.getModifyDate().getTime();

		synchronized (this) {
			if (modifyTime > m_modifyTime) {
				String content = config.getContent();
				AllTransactionConfig blackList = DefaultSaxParser.parse(content);

				m_config = blackList;
				m_modifyTime = modifyTime;
			}
		}
	}

	private boolean storeConfig() {
		synchronized (this) {
			try {
				Config config = m_configDao.createLocal();

				config.setId(m_configId);
				config.setKeyId(m_configId);
				config.setName(CONFIG_NAME);
				config.setContent(m_config.toString());
				m_configDao.updateByPK(config, ConfigEntity.UPDATESET_FULL);
			} catch (Exception e) {
				Cat.logError(e);
				return false;
			}
		}
		return true;
	}

	public boolean validate(String type) {
		return m_config.getTypes().containsKey(type);
	}

	public boolean validate(String type, String name) {
		Map<String, Type> types = m_config.getTypes();
		Type typeConfig = types.get(type);

		if (typeConfig != null) {
			List<Name> list = typeConfig.getNameList();

			for (Name nameConfig : list) {
				String configId = nameConfig.getId();

				if (configId.equals(name) || "*".equals(configId)) {
					return true;
				}
			}
		}
		return false;
	}

}
@@ -1584,11 +1584,9 @@
 ig;%0A
-   
+%09
 %7D%0A%0A%09
@@ -3694,51 +3694,115 @@
 %7B%0A%09%09
-return m_config.getTypes().containsKey(type
+Map%3CString, Type%3E types = m_config.getTypes();%0A%09%09%0A%09%09return types.containsKey(type) %7C%7C types.containsKey(%22*%22
 );%0A%09

modify the config