package jp.hasc.hasctool.ui.views.beanslist;

import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * @author iwasaki
 */
public class BeansListLoader {
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(BeansListLoader.class);
	
	public static final String EXTENTION_POINT_ID = "jp.hasc.hasctool.beanslist";
	public static final String ELEM_NAME_LIST_XML = "list-xml";
	public static final String ATTR_NAME_RESOURCE = "resource";
	
	public Collection<BeansFolder> makeModel() {
		BeansFolder rootFolder=new BeansFolder(null);
		
		IExtensionRegistry reg = Platform.getExtensionRegistry();
		IExtensionPoint po = reg.getExtensionPoint(EXTENTION_POINT_ID);
		if (po==null) return rootFolder.subFolders();
		for(IExtension ex:po.getExtensions()) {
			for(IConfigurationElement e: ex.getConfigurationElements()) {
				String name = e.getName();
				if (name.equals(ELEM_NAME_LIST_XML)) {
					String resName = e.getAttribute(ATTR_NAME_RESOURCE);
					//LOG.debug(resName);
					try {
						InputStream inps = getClass().getClassLoader().getResourceAsStream(resName);
						XStream xs=BeansListLoader.newXStream();
						@SuppressWarnings("unchecked")
						Collection<BeansFolder> listXml=(Collection<BeansFolder>)xs.fromXML(inps);
						for(BeansFolder f:listXml) {
							//LOG.debug(f.getName());
							mergeSubfolder(rootFolder,f);
						}
						inps.close();
					} catch (Exception ex2) {
						LOG.warn("Exception",ex2);
					}
				}else{
					LOG.warn("Unknown configuration element: "+name);
				}
			}
		}
		rootFolder.afterLoad();
		return rootFolder.subFolders();
	}

	private HashMap<BeansFolder, HashMap<String, BeansFolder>>
		subFolderMaps_ = new HashMap<BeansFolder, HashMap<String,BeansFolder>>();

	private void mergeSubfolder(BeansFolder folder, BeansFolder subFolder) {
		HashMap<String, BeansFolder> map = subFolderMaps_.get(folder);
		if (map==null) {
			map=new HashMap<String, BeansFolder>();
			subFolderMaps_.put(folder,map);
		}
		BeansFolder existingSubFolder = map.get(subFolder.getName());
		if (existingSubFolder==null) {
			folder.subFolders().add(subFolder);
			map.put(subFolder.getName(), subFolder);
		}else{
			existingSubFolder.classes().addAll(subFolder.classes());
		}
	}

	public static XStream newXStream() {
		XStream xs = new XStream(new DomDriver());
		xs.autodetectAnnotations(true);
		xs.aliasPackage("model", BeansFolder.class.getPackage().getName());
		return xs;
	}
}
