package td2jira.jira.http;

import java.io.File;
import java.io.FileOutputStream;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.log4j.Logger;

import td2jira.Config;
import td2jira.jira.JIRAIssue;

public class AddAttachmentToIssue {
	private static Logger logger = Logger.getLogger(AddAttachmentToIssue.class);
	
	public static void addAttachmentToIssue(JIRAIssue jiraIssue,String fileName, byte[] data) {
		try {
			logger.debug("adding attachment "+fileName+" to "+jiraIssue.getKey()+"...");
			
		    HttpClient httpclient = new HttpClient();

		    auth(httpclient);
		    doLogin(httpclient);
		    doAttach(httpclient, jiraIssue.getId(), fileName, data);
		} catch( Exception ex ) {
			throw new RuntimeException(ex);
		}
	}

	private static void auth(HttpClient httpclient) {
		if( Config.HTTP_PROXY_HOST != null ) {
			logger.debug("using proxy "+Config.HTTP_PROXY_HOST+":"+Config.HTTP_PROXY_PORT);
			
			HostConfiguration hc = httpclient.getHostConfiguration();
			hc.setProxy(Config.HTTP_PROXY_HOST,Integer.parseInt(Config.HTTP_PROXY_PORT));
			
			if( Config.HTTP_PROXY_USER != null ) {
				logger.debug("using proxy user "+Config.HTTP_PROXY_USER);
				Credentials proxyCredentials = null;
				
				int backSlash = Config.HTTP_PROXY_USER.indexOf('\\');
				if( backSlash > 0 ) {
					String domain = Config.HTTP_PROXY_USER.substring(0, backSlash);
					String user = Config.HTTP_PROXY_USER.substring(backSlash+1);
					String computer = "CBAD4-KCILR1";
					logger.debug("using NT proxy authorization: "+user+"@"+domain+" on "+computer);
					proxyCredentials = new NTCredentials(user,Config.HTTP_PROXY_PASSWORD,computer,domain);
				} else {
					proxyCredentials = new UsernamePasswordCredentials(Config.HTTP_PROXY_USER, Config.HTTP_PROXY_PASSWORD);
				}
				httpclient.getState().setCredentials(AuthScope.ANY, proxyCredentials);		    		
			}
		}
	}

	private static void doLogin(HttpClient httpclient) throws Exception {
		String loginUrl = Config.JIRA_URL+"/login.jsp";
		PostMethod login = new PostMethod(loginUrl);
		login.addParameter("os_username", Config.JIRA_USER);
		login.addParameter("os_password", Config.JIRA_PASSWORD);
		login.addParameter("os_destination", "/secure");
		
		int code = httpclient.executeMethod(login);
		String html = login.getResponseBodyAsString();
		if( html.indexOf("os_username") >= 0 ) {
			System.out.println("code:"+code);
			System.out.println(html);
			throw new RuntimeException("failed to login as "+Config.JIRA_USER); 
		}
	}

	private static void doAttach(HttpClient httpclient,String issueId,String fileName,byte[] data) throws Exception {
		File tmp = new File(fileName);
		tmp.deleteOnExit();
		
		FileOutputStream fos = new FileOutputStream(tmp);
		fos.write(data);
		fos.close();
		
	    String attachUrl = Config.JIRA_URL+"/secure/AttachFile.jspa?id="+issueId;
		
		PostMethod attach = new PostMethod(attachUrl);
		
		Part[] parts = { 
				new StringPart("multiple", "false"),
				new StringPart("id", issueId),
				new StringPart("Attach", "Attach"),
				new StringPart("comment", Config.SYNC_ATTACH_COMMENT_PREFIX+fileName),
				new StringPart("commentLevel", ""),
				new FilePart("filename.1", tmp)
				};
		
		// NB: gotta do it, otherwise JIRA corrupts attachments and mangles comments!!!
		for (Part part : parts) {
			if( part instanceof FilePart ) {
				FilePart fp = (FilePart) part;
				fp.setTransferEncoding(null);
			} else if( part instanceof StringPart ) {
				StringPart sp = (StringPart) part;
				sp.setTransferEncoding(null);
			}
		}
		
		attach.setRequestEntity(new MultipartRequestEntity(parts, attach.getParams()));
		
		httpclient.executeMethod(attach);
//		ByteArrayOutputStream baos = new ByteArrayOutputStream();
//		attach.getRequestEntity().writeRequest(baos);
//		baos.close();
//		fos = new FileOutputStream("req.txt");
//		fos.write(baos.toByteArray());
//		fos.close();
	}
}
