/*
* Licensed Materials - Property of IBM Corp.
* IBM UrbanCode Build
* (c) Copyright IBM Corporation 2012, 2014. All Rights Reserved.
*
* U.S. Government Users Restricted Rights - Use, duplication or disclosure restricted by
* GSA ADP Schedule Contract with IBM Corp.
*/
package com.urbancode.ubuild.plugin.rtcworkitems

import org.apache.commons.httpclient.*
import org.apache.commons.httpclient.methods.*
import org.apache.http.HttpResponse
import org.apache.http.NameValuePair
import org.apache.http.client.HttpClient
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.message.BasicNameValuePair
import org.apache.http.util.EntityUtils;

import com.urbancode.air.*
import com.urbancode.commons.util.IO

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_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 		// always ends with '/'
	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'] ?: props['automation/passScript'];
        url = props['automation/url'];
        if (!url.endsWith('/')) {
            url += '/'
        }
        projectName = props['automation/projectName'];
        this.apTool = apTool
    }

    def final authenticateRTCUser(HttpClient client){
        HttpGet getterMethod = null;
        HttpPost authMethod = null;
        try {
            getterMethod = new HttpGet(url + 'authenticated/identity');
            def getterResp = client.execute(getterMethod);
      
            authMethod = new HttpPost(url + 'authenticated/j_security_check');
            def data = [ new BasicNameValuePair("j_username", username),  new BasicNameValuePair("j_password", password)];
            authMethod.setEntity(new UrlEncodedFormEntity(data));
            //authMethod.setHeader(getterMethod.getRequestHeader("Cookie"));
            authMethod.setHeader(getterMethod.getFirstHeader("Host"));
            authMethod.setHeader(getterMethod.getFirstHeader("User-Agent"));
            
            getterMethod.releaseConnection();
            def authResponse = client.execute(authMethod);
           
            //getterMethod.setHeader(authMethod.getRequestHeader("Cookie"));
            getterMethod.setHeader(authMethod.getFirstHeader("Host"));
            getterMethod.setHeader(authMethod.getFirstHeader("User-Agent"));
            authMethod.releaseConnection();
            getterResp = client.execute(getterMethod);
            EntityUtils.consume(getterResp.getEntity());
            getterMethod.releaseConnection();
        }
        finally {
            if (authMethod != null) {
                authMethod.releaseConnection();
            }
        }
    }
    
    def final String getCatalogUrl(HttpClient client) {
        HttpGet rootServicesMethod=null;
        try {
            String rootServicesUrl = url + "rootservices"
            rootServicesMethod = new HttpGet(rootServicesUrl);
            System.out.println("Root Services URL = " + rootServicesUrl);
            rootServicesMethod.addHeader("Accept", "application/rdf+xml");
          	rootServicesMethod.setHeader("User-Agent", "Mozilla/5.0");
            HttpResponse rootServicesResult = client.execute(rootServicesMethod);
            def rtSrvcResp = IO.readText(rootServicesResult.entity.content)
            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) {
        HttpGet serviceDescriptor = null;
        try {
          serviceDescriptor = new HttpGet(rootServices);
          serviceDescriptor.setHeader("User-Agent", "Mozilla/5.0");
          HttpResponse response = client.execute(serviceDescriptor);
          def serviceResult = IO.readText(response.entity.content)
              
          def serviceXml = null;
          try { 
              serviceXml = new XmlParser(false, true).parseText(serviceResult);
          }
          catch (Exception e) {
              System.out.println(serviceResult);
              throw e;
          }
          
          String returnUrl =null;
          try {
              def projectService = serviceXml[n_oslc_disc.entry].find { it -> it[n_oslc_disc.ServiceProvider][n_dc.title].text().equals(projectName) }
              if (!projectService) {
                  throw new Exception("Project with name '${projectName}' not found in service listing.")
              }
              returnUrl = projectService[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 Credentials 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) {
        HttpGet getServices = null;
        try {
            getServices = new HttpGet(servicesUrl);
          	getServices.setHeader("User-Agent", "Mozilla/5.0");
            HttpResponse response = client.execute(getServices);
            def resp = IO.readText(response.entity.content)
            
            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) {
        HttpGet getServices = null;
        try {
            getServices = new HttpGet(servicesUrl);
          	getServices.setHeader("User-Agent", "Mozilla/5.0");
            HttpResponse response = client.execute(getServices);
            def resp = IO.readText(response.entity.content)
            
            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();
            }
        }
    }
}