package com.github.gotify.api import android.app.Activity import com.github.gotify.api.Callback.ErrorCallback import com.github.gotify.api.Callback.SuccessCallback import org.tinylog.kotlin.Logger import retrofit2.Call import retrofit2.Response internal class Callback private constructor( private val onSuccess: SuccessCallback, private val onError: ErrorCallback ) { fun interface SuccessCallback { fun onSuccess(response: Response) } fun interface SuccessBody : SuccessCallback { override fun onSuccess(response: Response) { onResultSuccess(response.body() ?: throw ApiException("null response", response)) } fun onResultSuccess(data: T) } fun interface ErrorCallback { fun onError(t: ApiException) } private class RetrofitCallback(private val callback: Callback) : retrofit2.Callback { override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { callback.onSuccess.onSuccess(response) } else { callback.onError.onError(ApiException(response)) } } override fun onFailure(call: Call, t: Throwable) { callback.onError.onError(ApiException(t)) } } companion object { fun callInUI( context: Activity, onSuccess: SuccessCallback, onError: ErrorCallback ): retrofit2.Callback { return call( onSuccess = { response -> context.runOnUiThread { onSuccess.onSuccess(response) } }, onError = { exception -> context.runOnUiThread { onError.onError(exception) } } ) } fun call( onSuccess: SuccessCallback = SuccessCallback {}, onError: ErrorCallback = ErrorCallback {} ): retrofit2.Callback { return RetrofitCallback(merge(of(onSuccess, onError), errorCallback())) } private fun of(onSuccess: SuccessCallback, onError: ErrorCallback): Callback { return Callback(onSuccess, onError) } private fun errorCallback(): Callback { return Callback( onSuccess = {}, onError = { exception -> Logger.error(exception, "Error while api call") } ) } private fun merge(left: Callback, right: Callback): Callback { return Callback( onSuccess = { data -> left.onSuccess.onSuccess(data) right.onSuccess.onSuccess(data) }, onError = { exception -> left.onError.onError(exception) right.onError.onError(exception) } ) } } }