//
// Created by Fear1ess on 2021/4/25.
//

#include <jni.h>
#include <zconf.h>
#include <string.h>
#include <malloc.h>
#include "wdun.h"
#include "wd_jni.h"
#include "https.h"

// by文杰
char* http_PostConnect(JNIEnv *env, char* url, unsigned char* post_Body, size_t len){
    int flag = 0;
    jbyteArray body_Array = (*env)->NewByteArray(env, len);
    (*env)->SetByteArrayRegion(env, body_Array, 0, 0, post_Body);
  //  jstring body = (*env)->NewStringUTF(env,post_Body);
 //   jstring body_Type = (*env)->NewStringUTF(env,"UTF-8");
 //   jarray body_Array = (wdCallObjectMethod(env, body, "getBytes","(Ljava/lang/String;)[B", body_Type));
    char* result=NULL;
    for(int i=0;i<3;++i){
        jobject connection=NULL;
        jobject bufferedReader=NULL;
        jobject strUrl=(*env)->NewStringUTF(env, url);
        jobject url=wdNewObject(env,"java/net/URL","(Ljava/lang/String;)V",strUrl);
        jobject proxy=wdGetStaticObjectField(env,"java/net/Proxy","NO_PROXY","Ljava/net/Proxy;");

        if(proxy!=0){
            jobject proxy_Type=wdCallObjectMethod(env,proxy,"type","()Ljava/net/Proxy$Type;");
            jstring proxy_Type_String=(jstring)wdCallObjectMethod(env,proxy_Type,"toString","()Ljava/lang/String;");
            char* proxy_Type_Str=(char* )(*env)->GetStringUTFChars(env,proxy_Type_String,0);
            if(strstr(proxy_Type_Str,"DIRECT")!=NULL){
                connection=wdCallObjectMethod(env,url,"openConnection","(Ljava/net/Proxy;)Ljava/net/URLConnection;",proxy);
                jstring post=(*env)->NewStringUTF(env,"POST");
                wdCallVoidMethod(env,connection,"setRequestMethod","(Ljava/lang/String;)V",post);
                jstring type=(*env)->NewStringUTF(env,"Content-Type");
                jstring type_Content=(*env)->NewStringUTF(env,"text/plain;charset=UTF-8");
                wdCallVoidMethod(env,connection,"setRequestProperty",
                                 "(Ljava/lang/String;Ljava/lang/String;)V",type,type_Content);
                wdCallVoidMethod(env,connection,"setDoInput",
                                 "(Z)V",1);
                wdCallVoidMethod(env,connection,"setDoOutput",
                                 "(Z)V",1);
                wdCallVoidMethod(env,connection,"setConnectTimeout",
                                 "(I)V",10000);
                wdCallVoidMethod(env,connection,"setReadTimeout",
                                 "(I)V",10000);
                jobject outPutStream=wdCallObjectMethod(env,connection,"getOutputStream","()Ljava/io/OutputStream;");
                jobject out=wdNewObject(env,"java/io/DataOutputStream","(Ljava/io/OutputStream;)V",outPutStream);
                wdCallVoidMethod(env,out,"write","([B)V",body_Array);
                wdCallVoidMethod(env,out,"flush","()V");
                wdCallVoidMethod(env,out,"close","()V");
                wdCallVoidMethod(env,connection,"connect","()V");
                if(1){
                    jobject inputStream= wdCallObjectMethod(env,connection,"getInputStream","()Ljava/io/InputStream;");
                    if(inputStream!=0){
                        jobject inputStreamReader=wdNewObject(env,"java/io/InputStreamReader","(Ljava/io/InputStream;)V",inputStream);
                        bufferedReader=wdNewObject(env,"java/io/BufferedReader","(Ljava/io/Reader;)V",inputStreamReader);
                        jobject response=wdNewObject(env,"java/lang/StringBuilder","()V");
                        jobject line=wdCallObjectMethod(env,bufferedReader,"readLine","()Ljava/lang/String;");;
                        while (line!=0){
                            wdCallObjectMethod(env,response,"append","(Ljava/lang/String;)Ljava/lang/StringBuilder;",line);
                            (*env)->DeleteLocalRef(env,line);
                            line=wdCallObjectMethod(env,bufferedReader,"readLine","()Ljava/lang/String;");
                        }
                        if (bufferedReader != 0) {
                            wdCallVoidMethod(env,bufferedReader,"close","()V");
                        }
                        if (connection != 0) {
                            wdCallVoidMethod(env,connection,"disconnect","()V");
                        }
                        jstring result_String=(jstring)wdCallObjectMethod(env,response,"toString","()Ljava/lang/String;");
                        char* result_Str_UTF8= (char*)((*env)->GetStringUTFChars(env,result_String, 0));
                        result=(char*)calloc(1,strlen(result_Str_UTF8) + 1);
                        memcpy(result,result_Str_UTF8,strlen(result_Str_UTF8));

                        (*env)->ReleaseStringUTFChars(env,result_String, result_Str_UTF8);
                        (*env)->DeleteLocalRef(env,result_String);
                        (*env)->DeleteLocalRef(env,line);
                        (*env)->DeleteLocalRef(env,response);
                        (*env)->DeleteLocalRef(env,inputStreamReader);
                        flag=1;

                    }
                    (*env)->DeleteLocalRef(env,inputStream);
                }
                (*env)->DeleteLocalRef(env,out);
                (*env)->DeleteLocalRef(env,outPutStream);
                (*env)->DeleteLocalRef(env,type_Content);
                (*env)->DeleteLocalRef(env,type);
                (*env)->DeleteLocalRef(env,post);

            }else{
                //proxy被修改
            }
            (*env)->ReleaseStringUTFChars(env,proxy_Type_String, proxy_Type_Str);
            (*env)->DeleteLocalRef(env,proxy_Type);
            (*env)->DeleteLocalRef(env,proxy_Type_String);

        }

        (*env)->DeleteLocalRef(env,proxy);
        (*env)->DeleteLocalRef(env,url);
        (*env)->DeleteLocalRef(env,strUrl);
        (*env)->DeleteLocalRef(env,bufferedReader);
        (*env)->DeleteLocalRef(env,connection);

        if(flag == 1){
            break;
        }else{
            sleep(1);
        }
    }
    (*env)->DeleteLocalRef(env, body_Array);
    return result;
}