package com.duolebo.blyrobot

import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.support.v4.content.LocalBroadcastManager
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Toast
import com.duolebo.appbase.AppBaseHandler
import com.duolebo.appbase.IAppBaseCallback
import com.duolebo.appbase.IProtocol
import com.duolebo.blyrobot.activity.PackageListActivity
import com.duolebo.blyrobot.data.ApkInfo
import com.duolebo.blyrobot.data.ApkPackageInfo
import com.duolebo.blyrobot.data.AppInfoData
import com.duolebo.blyrobot.data.Task
import com.duolebo.blyrobot.protocol.GetAppInfoProtocol
import com.duolebo.blyrobot.service.BylRobotService
import com.duolebo.blyrobot.tools.TaskManager
import com.duolebo.blyrobot.ui.AppConfigListItem
import com.duolebo.blyrobot.util.AdbUtil
import com.duolebo.blyrobot.util.Config
import com.duolebo.blyrobot.util.Constants
import com.minhui.vpn.utils.ThreadProxy
import kotlinx.android.synthetic.main.activity_main.*
import net.gotev.uploadservice.UploadNotificationConfig
import net.gotev.uploadservice.ftp.FTPUploadRequest
import net.gotev.uploadservice.ftp.UnixPermissions
import java.io.File
import java.util.*

class MainActivity : AppCompatActivity(), IAppBaseCallback {

    private val TAG = "MainActivity"
    private lateinit var apkInfoProtocol: GetAppInfoProtocol
    private lateinit var dataHandler: AppBaseHandler
    private lateinit var appInfoAdapter: AppConfigAdapter
    private lateinit var refreshTimer: Timer

    private var apkPackageInfo: List<ApkPackageInfo>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.i(TAG, "onCreate....")
        setContentView(R.layout.activity_main)

        getLocalAppList()

        this.appInfoAdapter = AppConfigAdapter()
        listView.adapter = this.appInfoAdapter

        initRefreshTimer()

        val hasRoot = AdbUtil.checkRootPermission()
        if (hasRoot) {
            Log.i(TAG, "rooted...")
            textView.setText(R.string.tips_device_rooted)
        }
        else {
            textView.setText(R.string.tips_device_not_root)
        }

        startRobotService()

        startBtn.setOnClickListener{
            startRobot()
        }

        stopBtn.setOnClickListener{
            stopRobot()
        }
        startBtn.requestFocus()

        requestAppList()

        testFtpUpload()
    }

    private fun requestAppList() {
        apkInfoProtocol = GetAppInfoProtocol(this, Config.instance)
        this.dataHandler = AppBaseHandler(this)
        apkInfoProtocol.execute(this.dataHandler)
    }

    private fun getLocalAppList() {
        ThreadProxy.getInstance().execute {
            apkPackageInfo = ApkPackageInfo.getAppInfos(applicationContext)
            runOnUiThread {
                appInfoAdapter.notifyDataSetChanged()
            }
        }
    }

    private fun initRefreshTimer() {
        refreshTimer = Timer()

        refreshTimer.schedule(object: TimerTask() {
            override fun run() {
                runOnUiThread {
                    updateListStatus()
                }
            }
        },2000, 2*60*1000)
    }

    private fun updateListStatus() {

    }

    private fun startRobotService() {
        startService(Intent(this, BylRobotService::class.java))
    }

    private fun startRobot() {
        Log.i(TAG, "startRobot...")
        val intent = Intent(Constants.ACTION_LOCAL_SERVICE)
        intent.putExtra(Constants.KEY_CMD, Constants.CMD_START)
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    private fun stopRobot() {
        val intent = Intent(Constants.ACTION_LOCAL_SERVICE)
        intent.putExtra(Constants.KEY_CMD,  Constants.CMD_STOP)
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    override fun onProtocolFailed(protocol: IProtocol?) {
        Toast.makeText(this, "获取应用列表信息出错", Toast.LENGTH_SHORT).show()
    }

    override fun onHttpFailed(protocol: IProtocol?) {
        Toast.makeText(this, "网络错误", Toast.LENGTH_SHORT).show()
    }

    override fun onProtocolSucceed(protocol: IProtocol?) {
        if (protocol is GetAppInfoProtocol) {
            val appInfoData =  protocol.data as AppInfoData
            this.appInfoAdapter.setData(appInfoData.apkInfos)
            this.appInfoAdapter.notifyDataSetChanged()

            for (apkInfo in appInfoData.apkInfos) {
                val task = Task(this.applicationContext)
                task.from(apkInfo)
                TaskManager.instance.add(task)
            }
        }
    }

    fun getAppIcon(packageName: String): Drawable? {
        var drawable:Drawable ?= null
        apkPackageInfo?.run {
            val targetPackage = this.find {
                it.packageName == packageName
            }

            if (targetPackage != null) {
                drawable = targetPackage.applicationInfo.loadIcon(packageManager)
            }
        }

        return drawable
    }

    fun testFtpUpload() {
        try {
            val uploadRequest = FTPUploadRequest(this, Config.instance.getFtpServer(), 21)
                    .setUsernameAndPassword(Config.instance.getFtpUserName(), Config.instance.getFtpPassword())
                    .setNotificationConfig(UploadNotificationConfig())
                    .setCreatedDirectoriesPermissions(UnixPermissions("777"))
                    .setMaxRetries(4)

            val uploadFile = File("/sdcard/shumei.txt")
            uploadRequest.addFileToUpload(uploadFile.absolutePath, Config.instance.getFtpRemotePath() + "/" + uploadFile.name)

            val uploadId = uploadRequest.startUpload()
            Log.i(TAG, "upload id $uploadId")
        } catch (exc: Exception) {
            Log.e(TAG, exc.message, exc)
        }
    }

    inner class AppConfigAdapter: BaseAdapter() {

        private val dataList = ArrayList<ApkInfo>()

        fun setData(dataList: ArrayList<ApkInfo>) {
            this.dataList.clear()
            this.dataList.addAll(dataList)
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
            var itemView: AppConfigListItem
            if (convertView == null) {
                itemView = AppConfigListItem(parent.context)
            }
            else
                itemView = convertView as AppConfigListItem

            itemView.setData(dataList[position])
            val drawable = getAppIcon(dataList[position].packageName)
            drawable?.run {
                itemView.setIcon(this)
            }

            return itemView
        }

        override fun getItem(position: Int): Any {
            return dataList[position]
        }

        override fun getItemId(position: Int): Long {
            return 0
        }

        override fun getCount(): Int {
            return dataList.size
        }

    }
}
