package logger

import (
	"fmt"
	"os"
	"strings"

	"github.com/rivo/tview"
	log "github.com/wtfutil/wtf/logger"
	"github.com/wtfutil/wtf/view"
)

const (
	maxBufferSize int64 = 1024
)

type Widget struct {
	view.TextWidget

	app      *tview.Application
	filePath string
	settings *Settings
}

func NewWidget(app *tview.Application, settings *Settings) *Widget {
	widget := Widget{
		TextWidget: view.NewTextWidget(app, settings.common),

		app:      app,
		filePath: log.LogFilePath(),
		settings: settings,
	}

	return &widget
}

// Refresh updates the onscreen contents of the widget
func (widget *Widget) Refresh() {
	widget.Redraw(widget.content)
}

/* -------------------- Unexported Functions -------------------- */

func (widget *Widget) content() (string, string, bool) {
	if log.LogFileMissing() {
		return widget.CommonSettings().Title, "File missing", false
	}

	logLines := widget.tailFile()
	str := ""

	for _, line := range logLines {
		chunks := strings.Split(line, " ")

		if len(chunks) >= 4 {
			str += fmt.Sprintf(
				"[green]%s[white] [yellow]%s[white] %s\n",
				chunks[0],
				chunks[1],
				strings.Join(chunks[3:], " "),
			)
		}
	}

	return widget.CommonSettings().Title, str, false
}

func (widget *Widget) tailFile() []string {
	file, err := os.Open(widget.filePath)
	if err != nil {
		return []string{}
	}
	defer func() { _ = file.Close() }()

	stat, err := file.Stat()
	if err != nil {
		return []string{}
	}

	bufferSize := maxBufferSize
	if maxBufferSize > stat.Size() {
		bufferSize = stat.Size()
	}

	startPos := stat.Size() - bufferSize

	buff := make([]byte, bufferSize)
	_, err = file.ReadAt(buff, startPos)
	if err != nil {
		return []string{}
	}

	logLines := strings.Split(string(buff), "\n")

	// Reverse the array of lines
	// Offset by two to account for the blank line at the end
	last := len(logLines) - 2
	for i := 0; i < len(logLines)/2; i++ {
		logLines[i], logLines[last-i] = logLines[last-i], logLines[i]
	}

	return logLines
}
