package org.eclipse.ganymede.webgen;

import java.io.File;
import java.io.FileReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//import javax.xml.parsers.DocumentBuilder;
//import javax.xml.parsers.DocumentBuilderFactory;
//
//import org.w3c.dom.Document;
//import org.w3c.dom.Element;
//import org.w3c.dom.Node;
//import org.xml.sax.InputSource;
//
// apparently I need to use <java fork="true"> to get the xml parsing to work under J9

public class Blame {
//	private static final DocumentBuilderFactory s_documentBuilderFactory = DocumentBuilderFactory
//			.newInstance();
//
//	static {
//		s_documentBuilderFactory.setIgnoringComments(true);
//		s_documentBuilderFactory.setValidating(false);
//		s_documentBuilderFactory.setNamespaceAware(false);
//	}

	private String key;
	private String url;
	private String projectid;
	private Map<String, String> emails;
	private String status_message;

	public Blame(String k, String u) {
		this.key = k;
		this.url = u;
	}

	public String getKey() {
		return this.key;
	}

	public Collection<String> getFailureEmailAddresses() {
		if (emails == null)
			return new HashSet<String>();
		return emails.values();
	}

	public String stringForStatusMessage() {
		if (this.status_message == null)
			getStatusMessageAndEmails();
		return this.status_message;
	}

	private void getStatusMessageAndEmails() {
		this.projectid = null;
		try {
			if (this.url.substring(0, 5).equals("file:")) {
				File f = new File(this.url.substring(5));
				FileReader in = new FileReader(f);
				char[] cbuf = new char[(int)f.length()];
				in.read(cbuf);
				String s = new String(cbuf);
				Pattern p = Pattern.compile("<sc:member\\s+name=\"(.*?)\"\\s+email=\"(.*?)\"\\s*/>");
				Matcher m = p.matcher(s);
				int idx = 0;
				while( m.find(idx) ) {
					idx = m.end();
					String name = m.group(1);
					String email = m.group(2);
					if (emails == null)
						emails = new HashMap<String, String>();
					emails.put(name, email);
				}
//				DocumentBuilder builder = s_documentBuilderFactory
//						.newDocumentBuilder();
//				InputSource source = new InputSource(new BufferedInputStream(
//						new FileInputStream(this.url.substring(5))));
//				source.setSystemId(this.url);
//				Document document = builder.parse(source);
//				Element topElement = document.getDocumentElement();
//
//				if (topElement.getNodeName().equals("sc:siteContribution")) {
//					String pid = topElement.getAttribute("projectId");
//					if (pid != null) {
//						this.projectid = pid;
//						this.status_message = pid;
//						// TODO turn the projectid into a project name using the
//						// Foundation db web-api
//					}
//					for (Node child = topElement.getFirstChild(); child != null; child = child
//							.getNextSibling()) {
//						if (child.getNodeType() == Node.ELEMENT_NODE
//								&& child.getNodeName().equals("sc:member")) {
//							Element elem = (Element) child;
//							String name = elem.getAttribute("name");
//							String email = elem.getAttribute("email");
//							if (emails == null)
//								emails = new HashMap<String, String>();
//							emails.put(name, email);
//						}
//					}
//				}
			}
		} catch (Exception x) {
			this.status_message = x.toString();
		}
		if (this.projectid == null || this.projectid.equals("")) {
			Pattern purl = Pattern.compile(".*/(.+?)\\.sc");
			Matcher m = purl.matcher(this.url);
			if (m.find()) {
				this.status_message = m.group(1);
			} else {
				this.status_message = this.url;
			}
		}
	}
}
