package com.cr.network

import com.cr.data.CrUtil
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.*
import java.io.IOException
import kotlin.jvm.JvmOverloads

/**
 * 操作系统：MAC系统
 * 创建者：王成
 * 创建日期：2023/8/26 16:56
 * 描述：自定义上传体 用于监听上传进度
 */
class CrProgressRequestBody @JvmOverloads constructor(
    requestBody:RequestBody,
    listener:ICallback?=null
) : RequestBody() {
    /**
     * 进度接口
     */
    interface ICallback{
        // todo: 2023/8/26 进度回调
        fun onProgress(currentBytes:Long,totalBytes:Long)

        // todo: 2023/8/26 错误回调
        fun onFailed(error:String)
    }
    private var requestBody:RequestBody?= null  // define: 2023/8/26 上传body
    private var listener:ICallback?= null // define: 2023/8/26 监听

    /**
     * 初始化
     */
    init {
        this.requestBody = requestBody
        this.listener = listener
    }

    /**
     * 覆写设置类型
     * @return MediaType?
     */
    override fun contentType(): MediaType? {
        return requestBody?.contentType()
    }

    /**
     * 覆写内容长度
     * @return Long
     */
    override fun contentLength(): Long {
        return requestBody!!.contentLength()
    }

    /**
     * 覆写写入进度
     * @param sink BufferedSink
     */
    override fun writeTo(sink: BufferedSink) {
        try {
            var bufferedSink = CountingSink(sink,object:ICallback{
                // todo: 2023/8/26 进度回调
                override fun onProgress(currentBytes: Long, totalBytes: Long) {
                    listener?.onProgress(currentBytes,contentLength())
                }

                // todo: 2023/8/26 错误
                override fun onFailed(error: String) {
                    listener?.onFailed(error)
                }
            }).buffer()
            requestBody?.writeTo(bufferedSink)
            bufferedSink.flush()
        }catch (e:IOException){
            listener?.onFailed(e.message!!)
        }
    }

    /**
     * ForwardingSink 实现类
     * @property bytesWritten Long
     * @property listener IProgressListener?
     * @constructor
     */
    private class CountingSink @JvmOverloads constructor(
        delegate:Sink,
        listener:ICallback?=null
    ) : ForwardingSink(delegate) {
        // define: 2023/8/26 长度
        private var bytesWritten:Long = 0
        private var listener:ICallback?= null

        /**
         * 初始化
         */
        init {
            this.listener = listener
        }

        /**
         * 覆写写入方法
         * @param source Buffer
         * @param byteCount Long
         */
        override fun write(source: Buffer, byteCount: Long) {
            super.write(source, byteCount)
            bytesWritten += byteCount
            listener?.onProgress(bytesWritten,0)
        }
    }
}