package com.manolovn.android.soapy;

import com.manolovn.android.soapy.annotations.SOAPMethod;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Soapy builder
 */
public class Soapy {

    final String endpoint;
    final String namespace;

    final HttpTransportSE httpTransportSE;

    private Soapy(String endpoint, String namespace) {
        this.endpoint = endpoint;
        this.namespace = namespace;

        this.httpTransportSE = getHttpTransportSE(endpoint);
    }

    private class SoapyHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


            // extract method name
            String methodname = "";
            if (method.isAnnotationPresent(SOAPMethod.class)) {
                System.out.println("SOAP METHOD " + method.getName());

                SOAPMethod methodNameAnnotation = method.getAnnotation(SOAPMethod.class);
                methodname = methodNameAnnotation.value();
            }
            SoapObject request = new SoapObject(namespace + "/", methodname);

            Annotation[][] annotations = method.getParameterAnnotations();
            for (Annotation[] ann : annotations) {
                System.out.printf("%d annotatations", ann.length);
                System.out.println();
            }

            // extract properties
            // request.addProperty("Celsius", celsius);

            SoapSerializationEnvelope envelope = getSoapSerializationEnvelope(request);

            httpTransportSE.call(namespace + "/" + methodname, envelope);

            //testHttpResponse(httpTransportSE);

            return envelope.getResponse().toString();
        }

    }

    @SuppressWarnings("unchecked")
    public <T> T create(Class<T> apiInterface) {
        return (T) Proxy.newProxyInstance(apiInterface.getClassLoader(), new Class<?>[]{apiInterface}, new SoapyHandler());
    }

    public static class Builder {
        private String endpoint;
        private String namespace;

        public Builder setEndpoint(String endpoint) {
            this.endpoint = endpoint;
            return this;
        }

        public Builder setNamespace(String namespace) {
            this.namespace = namespace;
            return this;
        }

        public Soapy build() {
            if (endpoint == null) {
                throw new IllegalArgumentException("Endpoint may not be null");
            }
            setDefaults();
            return new Soapy(endpoint, namespace);
        }

        private void setDefaults() {
            if (namespace == null) {
                namespace = endpoint;
            }
        }
    }

    /**
     * Serialize {@link org.ksoap2.serialization.SoapObject} to {@link org.ksoap2.serialization.SoapSerializationEnvelope}
     *
     * @param request : SOAP object to be serialized
     * @return : request serialized as SOAP envelope
     */
    protected final SoapSerializationEnvelope getSoapSerializationEnvelope(SoapObject request) {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.implicitTypes = true;
        envelope.setAddAdornments(false);
        envelope.setOutputSoapObject(request);

        return envelope;
    }

    /**
     * Returns SOAP HTTP transport
     *
     * @param baseUrl : base URL
     * @return {@link org.ksoap2.transport.HttpTransportSE}
     */
    protected final HttpTransportSE getHttpTransportSE(String baseUrl) {
        HttpTransportSE ht = new HttpTransportSE(java.net.Proxy.NO_PROXY, baseUrl, 60000);
        ht.debug = true;
        ht.setXmlVersionTag("<!--?xml version=\"1.0\" encoding= \"UTF-8\" ?-->");
        return ht;
    }

}

@@ -84,24 +84,84 @@
 SOAPMethod;%0A
+import com.manolovn.android.soapy.annotations.SOAPProperty;%0A
 import org.k
@@ -994,17 +994,16 @@
 able %7B%0A%0A
-%0A
         
@@ -1470,17 +1470,26 @@
 ion%5B%5D%5B%5D 
-a
+parameterA
 nnotatio
@@ -1543,33 +1543,138 @@
     
-for (Annotation%5B%5D ann : a
+Class%5B%5D parameterTypes = method.getParameterTypes();%0A%0A            int i = 0;%0A            for(Annotation%5B%5D annotations : parameterA
 nnot
@@ -1680,17 +1680,16 @@
 tations)
- 
 %7B%0A      
@@ -1702,57 +1702,247 @@
     
-System.out.printf(%22%25d annotatations%22, ann.length)
+Class parameterType = parameterTypes%5Bi++%5D;%0A%0A                for(Annotation annotation : annotations)%7B%0A                    if(annotation instanceof SOAPProperty)%7B%0A                        SOAPProperty myAnnotation = (SOAPProperty) annotation
 ;%0A  
@@ -1947,32 +1947,40 @@
                 
+ 
+       
 System.out.print
@@ -1982,16 +1982,51 @@
 println(
+%22param: %22 + parameterType.getName()
 );%0A     
@@ -2024,35 +2024,32 @@
 ));%0A            
-%7D%0A%0A
             // e
@@ -2048,30 +2048,65 @@
     
-// extract properties%0A
+System.out.println(%22value: %22 + myAnnotation.value());%0A   
     
@@ -2113,18 +2113,24 @@
         
-//
+        
  request
@@ -2146,28 +2146,93 @@
 rty(
-%22Celsius%22, celsius);
+myAnnotation.value(), args%5B0%5D);%0A                    %7D%0A                %7D%0A            %7D
 %0A%0A  
@@ -2309,33 +2309,32 @@
 elope(request);%0A
-%0A
             http
@@ -2387,25 +2387,24 @@
  envelope);%0A
-%0A
             
@@ -2440,17 +2440,16 @@
 ortSE);%0A
-%0A
         

add import