package com.nextcloud.android.sso.helper;

import com.nextcloud.android.sso.aidl.NextcloudRequest;
import com.nextcloud.android.sso.api.NextcloudAPI;

import java.lang.reflect.Type;

import okhttp3.Request;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 *  Nextcloud SingleSignOn
 *
 *  @author David Luhmer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public final class Retrofit2Helper {

    private Retrofit2Helper() { }

    public static <T> Call<T> WrapInCall(final NextcloudAPI nextcloudAPI, final NextcloudRequest nextcloudRequest, 
                                         final Type resType) {
        return new Call<T>() {
            @Override
            public Response<T> execute() {
                try {
                    T body = nextcloudAPI.performRequest(resType, nextcloudRequest);
                    return Response.success(body);
                } catch (Exception e) {
                    return Response.error(520, ResponseBody.create(null, e.toString()));
                }
            }

            @Override
            public void enqueue(Callback<T> callback) {
                callback.onResponse(null, execute());
            }

            @Override
            public boolean isExecuted() {
                throw new UnsupportedOperationException("Not implemented");
            }

            @Override
            public void cancel() {
                throw new UnsupportedOperationException("Not implemented");
            }

            @Override
            public boolean isCanceled() {
                throw new UnsupportedOperationException("Not implemented");
            }

            @Override
            public Call<T> clone() {
                throw new UnsupportedOperationException("Not implemented");
            }

            @Override
            public Request request() {
                throw new UnsupportedOperationException("Not implemented");
            }
        };
    }


    /**
     *
     * @param success if true, a Response.success will be returned, otherwise Response.error(520)
     * @return
     */
    public static Call<Void> WrapVoidCall(final boolean success) {
        return new Call<Void>() {
            @Override
            public Response<Void> execute() {
                if(success) {
                    return Response.success(null);
                } else {
                    return Response.error(520, null);
                }
            }

            @Override
            public void enqueue(Callback callback) {
                if(success) {
                    callback.onResponse(null, Response.success(null));
                } else {
                    callback.onResponse(null, Response.error(520, null));
                }
            }

            @Override
            public boolean isExecuted() {
                return true;
            }

            @Override
            public void cancel() { }

            @Override
            public boolean isCanceled() {
                return false;
            }

            @Override
            public Call<Void> clone() {
                return null;
            }

            @Override
            public Request request() {
                throw new UnsupportedOperationException("Not implemented");
            }
        };

    }

}

@@ -36,16 +36,60 @@
 elper;%0A%0A
+import android.support.annotation.NonNull;%0A%0A
 import c
@@ -220,16 +220,42 @@
 .Type;%0A%0A
+import okhttp3.MediaType;%0A
 import o
@@ -299,16 +299,44 @@
 seBody;%0A
+import okio.BufferedSource;%0A
 import r
@@ -1900,20 +1900,20 @@
 esponse(
-null
+this
 , execut
@@ -3169,20 +3169,33 @@
 or(520, 
-null
+emptyResponseBody
 );%0A     
@@ -3268,32 +3268,41 @@
 ic void enqueue(
+@NonNull 
 Callback callbac
@@ -3368,36 +3368,36 @@
 back.onResponse(
-null
+this
 , Response.succe
@@ -3472,20 +3472,20 @@
 esponse(
-null
+this
 , Respon
@@ -3498,20 +3498,33 @@
 or(520, 
-null
+emptyResponseBody
 ));%0A    
@@ -4105,10 +4105,369 @@
 %0A    %7D%0A%0A
+    private static ResponseBody emptyResponseBody = new ResponseBody() %7B%0A        @Override%0A        public MediaType contentType() %7B%0A            return null;%0A        %7D%0A%0A        @Override%0A        public long contentLength() %7B%0A            return 0;%0A        %7D%0A%0A        @Override%0A        public BufferedSource source() %7B%0A            return null;%0A        %7D%0A    %7D;%0A%0A
 %7D%0A

fix NullPointerException if request fails