/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.fenix.home.sessioncontrol.viewholders

import android.text.method.ScrollingMovementMethod
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.TorBootstrapLoggerBinding
import org.mozilla.fenix.tor.TorEvents
import org.mozilla.fenix.components.Components

class TorBootstrapLoggerViewHolder(
    private val view: View,
    private val components: Components
) : RecyclerView.ViewHolder(view), TorEvents {

    private var entries = mutableListOf<String>()
    private var binding: TorBootstrapLoggerBinding

    init {
        binding = TorBootstrapLoggerBinding.bind(view)
        components.torController.registerTorListener(this)

        val currentEntries = components.torController.logEntries
                .filter { it.first != null }
                .filter { !(it.first!!.startsWith("Circuit") && it.second == "ON") }
                // Keep synchronized with format in onTorStatusUpdate
                .flatMap { listOf("(${it.second}) '${it.first}'") }
        val entriesLen = currentEntries.size
        val subListOffset = if (entriesLen > MAX_NEW_ENTRIES) MAX_NEW_ENTRIES else entriesLen
        entries = currentEntries.subList((entriesLen - subListOffset), entriesLen) as MutableList<String>
        val initLog = "---------------" + view.resources.getString(R.string.tor_initializing_log) + "---------------"
        entries.add(0, initLog)

        with(binding.torBootstrapLogEntries) {
            movementMethod = ScrollingMovementMethod()
            text = formatLogEntries(entries)
        }
    }

    private fun formatLogEntries(entries: List<String>) = entries.joinToString("\n")

    @SuppressWarnings("EmptyFunctionBlock")
    override fun onTorConnecting() {
    }

    override fun onTorConnected() {
        components.torController.unregisterTorListener(this)
    }

    @SuppressWarnings("EmptyFunctionBlock")
    override fun onTorStopped() {
    }

    override fun onTorStatusUpdate(entry: String?, status: String?) {
        if (status == null || entry == null) return
        if (status == "ON" && entry.startsWith("Circuit")) return

        if (entries.size > MAX_LINES) {
            entries = entries.drop(1) as MutableList<String>
        }
        entries.add("($status) '$entry'")

        binding.torBootstrapLogEntries.text = formatLogEntries(entries)
    }

    companion object {
        const val LAYOUT_ID = R.layout.tor_bootstrap_logger
        const val MAX_NEW_ENTRIES = 24
        const val MAX_LINES = 25
    }
}
