///*
// * Copyright 2016 JetBrains s.r.o.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//
//@file:Suppress("unused")
//
//package org.jetbrains.anko
//
//import android.app.Activity
//import android.content.Context
//import android.os.Handler
//import android.os.Looper
//import androidx.fragment.app.Fragment
//import java.lang.ref.WeakReference
//import java.util.concurrent.ExecutorService
//import java.util.concurrent.Executors
//import java.util.concurrent.Future
//
///**
// * Execute [f] on the application UI thread.
// */
//fun Context.runOnUiThread(f: Context.() -> Unit) {
//    if (Looper.getMainLooper() === Looper.myLooper()) f() else ContextHelper.handler.post { f() }
//}
//
///**
// * Execute [f] on the application UI thread.
// */
//inline fun Fragment.runOnUiThread(crossinline f: () -> Unit) {
//    requireContext().runOnUiThread { f() }
//}
//
//class AnkoAsyncContext<T>(val weakRef: WeakReference<T>)
//
///**
// * Execute [f] on the application UI thread.
// * If the [doAsync] receiver still exists (was not collected by GC),
// *  [f] gets it as a parameter ([f] gets null if the receiver does not exist anymore).
// */
//fun <T> AnkoAsyncContext<T>.onComplete(f: (T?) -> Unit) {
//    val ref = weakRef.get()
//    if (Looper.getMainLooper() === Looper.myLooper()) {
//        f(ref)
//    } else {
//        ContextHelper.handler.post { f(ref) }
//    }
//}
//
///**
// * Execute [f] on the application UI thread.
// * [doAsync] receiver will be passed to [f].
// * If the receiver does not exist anymore (it was collected by GC), [f] will not be executed.
// */
//fun <T> AnkoAsyncContext<T>.uiThread(f: (T) -> Unit): Boolean {
//    val ref = weakRef.get() ?: return false
//    if (Looper.getMainLooper() === Looper.myLooper()) {
//        f(ref)
//    } else {
//        ContextHelper.handler.post { f(ref) }
//    }
//    return true
//}
//
///**
// * Execute [f] on the application UI thread if the underlying [Activity] still exists and is not finished.
// * The receiver [Activity] will be passed to [f].
// *  If it is not exist anymore or if it was finished, [f] will not be called.
// */
//fun <T : Activity> AnkoAsyncContext<T>.activityUiThread(f: (T) -> Unit): Boolean {
//    val activity = weakRef.get() ?: return false
//    if (activity.isFinishing) return false
//    activity.runOnUiThread { f(activity) }
//    return true
//}
//
//fun <T : Activity> AnkoAsyncContext<T>.activityUiThreadWithContext(f: Context.(T) -> Unit): Boolean {
//    val activity = weakRef.get() ?: return false
//    if (activity.isFinishing) return false
//    activity.runOnUiThread { activity.f(activity) }
//    return true
//}
//
//@JvmName("activityContextUiThread")
//fun <T : Activity> AnkoAsyncContext<AnkoContext<T>>.activityUiThread(f: (T) -> Unit): Boolean {
//    val activity = weakRef.get()?.owner ?: return false
//    if (activity.isFinishing) return false
//    activity.runOnUiThread { f(activity) }
//    return true
//}
//
//@JvmName("activityContextUiThreadWithContext")
//fun <T : Activity> AnkoAsyncContext<AnkoContext<T>>.activityUiThreadWithContext(f: Context.(T) -> Unit): Boolean {
//    val activity = weakRef.get()?.owner ?: return false
//    if (activity.isFinishing) return false
//    activity.runOnUiThread { activity.f(activity) }
//    return true
//}
//
//@Deprecated(message = "Use support library fragments instead. Framework fragments were deprecated in API 28.")
//fun <T : Fragment> AnkoAsyncContext<T>.fragmentUiThread(f: (T) -> Unit): Boolean {
//    val fragment = weakRef.get() ?: return false
//    if (fragment.isDetached) return false
//    val activity = fragment.activity ?: return false
//    activity.runOnUiThread { f(fragment) }
//    return true
//}
//
//@Deprecated(message = "Use support library fragments instead. Framework fragments were deprecated in API 28.")
//fun <T : Fragment> AnkoAsyncContext<T>.fragmentUiThreadWithContext(f: Context.(T) -> Unit): Boolean {
//    val fragment = weakRef.get() ?: return false
//    if (fragment.isDetached) return false
//    val activity = fragment.activity ?: return false
//    activity.runOnUiThread { activity.f(fragment) }
//    return true
//}
//
//private val crashLogger = { throwable: Throwable -> throwable.printStackTrace() }
//
///**
// * Execute [task] asynchronously.
// *
// * @param exceptionHandler optional exception handler.
// *  If defined, any exceptions thrown inside [task] will be passed to it. If not, exceptions will be ignored.
// * @param task the code to execute asynchronously.
// */
//fun <T> T.doAsync(
//    exceptionHandler: ((Throwable) -> Unit)? = crashLogger,
//    task: AnkoAsyncContext<T>.() -> Unit,
//): Future<Unit> {
//    val context = AnkoAsyncContext(WeakReference(this))
//    return BackgroundExecutor.submit {
//        return@submit try {
//            context.task()
//        } catch (thr: Throwable) {
//            val result = exceptionHandler?.invoke(thr)
//            result ?: Unit
//        }
//    }
//}
//
//fun <T> T.doAsync(
//    exceptionHandler: ((Throwable) -> Unit)? = crashLogger,
//    executorService: ExecutorService,
//    task: AnkoAsyncContext<T>.() -> Unit,
//): Future<Unit> {
//    val context = AnkoAsyncContext(WeakReference(this))
//    return executorService.submit<Unit> {
//        try {
//            context.task()
//        } catch (thr: Throwable) {
//            exceptionHandler?.invoke(thr)
//        }
//    }
//}
//
//fun <T, R> T.doAsyncResult(
//    exceptionHandler: ((Throwable) -> Unit)? = crashLogger,
//    task: AnkoAsyncContext<T>.() -> R,
//): Future<R> {
//    val context = AnkoAsyncContext(WeakReference(this))
//    return BackgroundExecutor.submit {
//        try {
//            context.task()
//        } catch (thr: Throwable) {
//            exceptionHandler?.invoke(thr)
//            throw thr
//        }
//    }
//}
//
//fun <T, R> T.doAsyncResult(
//    exceptionHandler: ((Throwable) -> Unit)? = crashLogger,
//    executorService: ExecutorService,
//    task: AnkoAsyncContext<T>.() -> R,
//): Future<R> {
//    val context = AnkoAsyncContext(WeakReference(this))
//    return executorService.submit<R> {
//        try {
//            context.task()
//        } catch (thr: Throwable) {
//            exceptionHandler?.invoke(thr)
//            throw thr
//        }
//    }
//}
//
//internal object BackgroundExecutor {
//    @Suppress("MemberVisibilityCanBePrivate")
//    var executor: ExecutorService =
//        Executors.newScheduledThreadPool(2 * Runtime.getRuntime().availableProcessors())
//
//    fun <T> submit(task: () -> T): Future<T> = executor.submit(task)
//}
//
//private object ContextHelper {
//    val handler = Handler(Looper.getMainLooper())
//}
