package single

import (
	"time"

	"github.com/bcicen/ctop/models"
	ui "github.com/gizak/termui"
)

type LogLines struct {
	ts   []time.Time
	data []string
}

func NewLogLines(max int) *LogLines {
	ll := &LogLines{
		ts:   make([]time.Time, max),
		data: make([]string, max),
	}
	return ll
}

func (ll *LogLines) tail(n int) []string {
	lines := make([]string, n)
	for i := 0; i < n; i++ {
		lines = append(lines, ll.data[len(ll.data)-i])
	}
	return lines
}
func (ll *LogLines) getLines(start, end int) []string {
	if end < 0 {
		return ll.data[start:]
	}
	return ll.data[start:end]
}

func (ll *LogLines) add(l models.Log) {
	if len(ll.data) == cap(ll.data) {
		ll.data = append(ll.data[:0], ll.data[1:]...)
		ll.ts = append(ll.ts[:0], ll.ts[1:]...)
	}
	ll.ts = append(ll.ts, l.Timestamp)
	ll.data = append(ll.data, l.Message)
	log.Debugf("recorded log line: %v", l)
}

type Logs struct {
	*ui.List
	lines *LogLines
}

func NewLogs(stream chan models.Log) *Logs {
	p := ui.NewList()
	p.Y = ui.TermHeight() / 2
	p.X = 0
	p.Height = ui.TermHeight() - p.Y
	p.Width = ui.TermWidth()
	//p.Overflow = "wrap"
	p.ItemFgColor = ui.ThemeAttr("par.text.fg")
	i := &Logs{p, NewLogLines(4098)}
	go func() {
		for line := range stream {
			i.lines.add(line)
			ui.Render(i)
		}
	}()
	return i
}

func (w *Logs) Align() {
	w.X = colWidth[0]
	w.List.Align()
}

func (w *Logs) Buffer() ui.Buffer {
	maxLines := w.Height - 2
	offset := len(w.lines.data) - maxLines
	w.Items = w.lines.getLines(offset, -1)
	return w.List.Buffer()
}

// number of rows a line will occupy at current panel width
func (w *Logs) lineHeight(s string) int { return (len(s) / w.InnerWidth()) + 1 }