package com.urbancode.ubuild.plugin.rtcworkitems

import com.urbancode.air.*

import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.params.HttpMethodParams;

public class RTCWorkItemHelper {
    
    //*****************************************************************************************************************
    // CLASS
    //*****************************************************************************************************************
    
    static final def n_rdf = new groovy.xml.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
    static final def n_dc = new groovy.xml.Namespace("http://purl.org/dc/terms/");
    static final def n_jfs = new groovy.xml.Namespace("http://jazz.net/xmlns/prod/jazz/jfs/1.0/");
    static final def n_jd = new groovy.xml.Namespace("http://jazz.net/xmlns/prod/jazz/discovery/1.0/");
    static final def n_jp06 = new groovy.xml.Namespace("http://jazz.net/xmlns/prod/jazz/process/0.6/");
    static final def n_rdf_about = new groovy.xml.Namespace("https://10.15.6.26:9443/jazz/rootservices");
    static final def n_oslc_cm = new groovy.xml.Namespace("http://open-services.net/xmlns/cm/1.0/");
    static final def n_oslc_disc = new groovy.xml.Namespace("http://open-services.net/xmlns/discovery/1.0/");
    static final def n_rtc_cm = new groovy.xml.Namespace('http://jazz.net/xmlns/prod/jazz/rtc/cm/1.0/');
    
    //*****************************************************************************************************************
    // INSTANCE
    //*****************************************************************************************************************
    
	def username
	def password
	String url
	def projectName
    final def out = System.out
    final def workDir = new File('.').canonicalFile
    final def apTool
    
    public RTCWorkItemHelper(Map<String,String> props, apTool) {
        username = props['automation/username'];
        password = props['automation/password'];
        url = props['automation/url'];
        projectName = props['automation/projectName'];
        this.apTool = apTool
    }

    def final authenticateRTCUser(String url, HttpClient client){
        HttpMethod getterMethod = null;
        HttpMethod authMethod = null;
        try {
            def tempURL = new URL(url);
            def path = "";
            if (tempURL.getPath().lastIndexOf("jazz") > 0 ) {
                path = tempURL.getPath().substring(0, tempURL.getPath().lastIndexOf("jazz") + 4);
            }
            else {
                path = tempURL.getPath().substring(0, tempURL.getPath().lastIndexOf("ccm") + 3);
            }
            
            def host = tempURL.getProtocol() + '://' + tempURL.getHost() + ':' + tempURL.getPort() + path;
//            println host;
            getterMethod = new GetMethod(host + '/authenticated/identity');
            
            client.executeMethod(getterMethod);
            
            authMethod = new PostMethod(host + '/authenticated/j_security_check');
            NameValuePair[] data = [ new NameValuePair("j_username", username), new NameValuePair("j_password", password) ];
            authMethod.setRequestBody(data);
            //authMethod.setRequestHeader(getterMethod.getRequestHeader("Cookie"));
            authMethod.setRequestHeader(getterMethod.getRequestHeader("Host"));
            authMethod.setRequestHeader(getterMethod.getRequestHeader("User-Agent"));
            
            getterMethod.releaseConnection();
            client.executeMethod(authMethod);
            
            //getterMethod.setRequestHeader(authMethod.getRequestHeader("Cookie"));
            getterMethod.setRequestHeader(authMethod.getRequestHeader("Host"));
            getterMethod.setRequestHeader(authMethod.getRequestHeader("User-Agent"));
            authMethod.releaseConnection();
            client.executeMethod(getterMethod);
            getterMethod.getResponseBodyAsString();
            getterMethod.releaseConnection();
        }
        finally {
            if(authMethod != null) {
                authMethod.releaseConnection();
            }
        }
    }
    
    def final String getCatalogUrl(HttpClient client) {
        HttpMethod rootServicesMethod=null;
        try {
            String rootServicesUrl = url;
            if (!rootServicesUrl.endsWith('/')) {
                rootServicesUrl += '/'
            }
            rootServicesUrl += "rootservices"
            rootServicesMethod = new GetMethod(rootServicesUrl);
            System.out.println("Root Services URL = " + rootServicesUrl);
            rootServicesMethod.setRequestHeader("Accept", "application/rdf+xml");
            def rootServicesResult = client.executeMethod(rootServicesMethod);
            def rtSrvcResp = rootServicesMethod.getResponseBodyAsString();
            def srvcxml = null;
            try { 
                srvcxml = new XmlParser().parseText(rtSrvcResp)
            }
            catch (Exception e) {
                System.out.println(rtSrvcResp);
                throw e;
            }
            def catalogUrl = srvcxml[n_oslc_cm.cmServiceProviders][0].attributes()[n_rdf.'resource'];
            System.out.println("Catalog URL = " + catalogUrl);
            return catalogUrl;
        } 
        finally {
            if(rootServicesMethod != null) {
                rootServicesMethod.releaseConnection()
            }
        }
    }

    def final String getServicesUrl(String rootServices, HttpClient client) {
        HttpMethod serviceDescriptor = null;
        try {
          serviceDescriptor = new GetMethod(rootServices);
//          serviceDescriptor.setRequestHeader("Accept", "application/x-oslc-cm-service-description+xml");
          client.executeMethod(serviceDescriptor);
          def serviceResult = serviceDescriptor.getResponseBodyAsString();
              
          def serviceXml = null;
          try { 
              serviceXml = new XmlParser(false, true).parseText(serviceResult);
          }
          catch (Exception e) {
              System.out.println(serviceResult);
              throw e;
          }
          
          String returnUrl =null;
          try {
              returnUrl = serviceXml[n_oslc_disc.entry].find { it -> it[n_oslc_disc.ServiceProvider][n_dc.title].text().equals(projectName) }[n_oslc_disc.ServiceProvider][n_oslc_disc.services][0].attributes()[n_rdf.'resource'];
          }
          catch (Exception e) {
              System.out.println("Error getting the Services Url: Check Project Name and Credientials are accurate!");
              System.out.println(serviceResult);
              throw e;
          }
          System.out.println("Services URL = " + returnUrl);
          return returnUrl;
        }
        finally {
            if(serviceDescriptor != null) {
                serviceDescriptor.releaseConnection();
            }
        }
    }
    
    def final String getWorkItemUrl(String servicesUrl, HttpClient client) {
        HttpMethod getServices = null;
        try {
            getServices = new GetMethod(servicesUrl);
            client.executeMethod(getServices);
            def resp = getServices.getResponseBodyAsString();
            
            def respXml = null;
            
            try {
                respXml = new XmlParser().parseText(resp);
            }
            catch (Exception e) {
                System.out.println(resp);
                throw e;
            }
            
            return respXml[n_oslc_cm.changeRequests][n_oslc_cm.simpleQuery][n_oslc_cm.url].text();
        }
        finally {
            if(getServices!=null) {
                getServices.releaseConnection();
            }
        }
    }
    
    def final String getCreationUrl(String servicesUrl, HttpClient client) {
        HttpMethod getServices = null;
        try {
            getServices = new GetMethod(servicesUrl);
            client.executeMethod(getServices);
            def resp = getServices.getResponseBodyAsString();
            
            def respXml = null;
            
            try {
                respXml = new XmlParser().parseText(resp);
            }
            catch (Exception e) {
                System.out.println(resp);
                throw e;
            }
            def creationUrl = respXml[n_oslc_cm.changeRequests][n_oslc_cm.factory].find { it -> it.attributes()[n_oslc_cm.'default'].equals("true") } [n_oslc_cm.url].text();
            System.out.println("Creation URL = " + creationUrl);
           return creationUrl;
        }
        finally {
            if(getServices!=null) {
                getServices.releaseConnection();
            }
        }
    }
}