package com.pmease.quickbuild.plugin.tracker.redmine;

import java.util.Date;
import java.util.Map;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.joda.time.format.ISODateTimeFormat;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.pmease.quickbuild.Context;
import com.pmease.quickbuild.plugin.report.engine.util.XMLHelper;
import com.pmease.quickbuild.plugin.tracker.core.extensionpoint.Issue;

public class RedmineHelper {
	public static Issue parseIssue(String xml) {
		if (Strings.isNullOrEmpty(xml)) {
			return null;
		}
		
		Issue issue = new Issue();
		Document doc = XMLHelper.readXML(xml);
		Element root = doc.getRootElement();
		issue.setIssueKey(root.elementText("id"));
		issue.setSummary(root.elementText("subject"));
		issue.setCreated(parseDate(root.elementText("created_on")));
		issue.setUpdated(parseDate(root.elementText("updated_on")));
		issue.setAssignee(root.valueOf("./assigned_to/@name"));
		issue.setIssueType(root.valueOf("./tracker/@name"));
		issue.setReporter(root.valueOf("./author/@name"));
		issue.setStatus(root.valueOf("./status/@name"));
		issue.setPriority(root.valueOf("./priority/@name"));
		
		return issue;
	}
	
    static final String ID              = "id";
	static final String PROJECT_ID      = "project_id";
	static final String TRACKER_ID      = "tracker_id";
	static final String STATUS_ID       = "status_id";
	static final String PRIORITY_ID     = "priority_id";
	static final String AUTHOR_ID       = "author_id";
	static final String ASSIGNED_TO_ID  = "assigned_to_id";
	static final String SUBJECT         = "subject";
	static final String DESCRIPTION     = "description";
	static final String FIX_VERSION_ID  = "fix_version_id";
	static final String START_DATE      = "start_date";
	static final String DUE_DATE        = "due_date";
	static final String DONE_RATIO      = "done_ratio";
	static final String ESTIMATED_HOURS = "estimated_hours";
	static final String SPENT_HOURS     = "spent_hours";
	static final String CREATED_ON      = "created_on";
	static final String UPDATED_ON      = "updated_on";
	static final String CUSTOM_FIELD    = "cf_";

	static final String TRACKER         = "tracker";
	static final String PRIORITY        = "priority";
	static final String STATUS          = "status";
	static final String ASSIGNED_TO     = "assigned_to";
	static final String AUTHOR          = "author";

	
	static Set<String> SUPPORTED_FIELDS_OF_CREATE = ImmutableSet.<String>of(
				ID, 
				TRACKER_ID, 
				STATUS_ID, 
				PRIORITY_ID, 
				AUTHOR_ID, 
				ASSIGNED_TO_ID, 
				SUBJECT, 
				DESCRIPTION, 
				FIX_VERSION_ID,
				START_DATE, 
				DUE_DATE, 
				DONE_RATIO,
				ESTIMATED_HOURS, 
				SPENT_HOURS, 
				CREATED_ON,
				UPDATED_ON
			);
	
	public static Document mapToIssueDocument(Map<String, String> map) {
		Document doc = DocumentHelper.createDocument();
		Element root = doc.addElement("issue");
		
		Element customNode = null;

		for (String each : map.keySet()) {
			if (each.startsWith(CUSTOM_FIELD)) {
				if (customNode == null) {
					customNode = root.addElement("custom_fields");
					customNode.addAttribute("type", "array");
				}
				
				Element n = customNode.addElement("custom_field");
				n.addAttribute("id", each.substring(CUSTOM_FIELD.length()));
				Element valueNode = n.addElement("value");
				valueNode.setText(map.get(each));
			} else if (SUPPORTED_FIELDS_OF_CREATE.contains(each)) {
				Element node = root.addElement(each);
				node.setText(map.get(each));
			} else {
				Context.getLogger().warn("The property " + each + " is unsupported, ignore ...");
			}
		}
		
		return doc;
	}
	
	static Date parseDate(String str) {
		return ISODateTimeFormat.dateTimeNoMillis().parseDateTime(str).toDate();
	}
}
