package words

import (
	"bufio"
	"io"
	"strings"
)

type List struct {
	words [][]string
	len   int
}

func newList(words []string) List {
	return List{
		words: [][]string{words},
		len:   len(words),
	}
}

func NewList(words []string) List {
	cleaned := make([]string, 0, len(words))
	for _, w := range words {
		w = strings.TrimSpace(w)
		w = strings.ToUpper(w)
		cleaned = append(cleaned, w)
	}
	return newList(cleaned)
}

func NewListFromLines(r io.Reader) List {
	var words []string
	scanner := bufio.NewScanner(r)

	for scanner.Scan() {
		word := scanner.Text()
		word = strings.TrimSpace(word)
		word = strings.ToUpper(word)
		if word != "" {
			words = append(words, word)
		}
	}

	return newList(words)
}

func (l *List) Len() int {
	return l.len
}

func (l *List) Get(i int) string {
	for _, words := range l.words {
		if i < len(words) {
			return words[i]
		}
		i -= len(words)
	}
	panic("out of bounds")
}

func (l List) Concat(other List) List {
	words := make([][]string, 0, len(l.words)+len(other.words))
	words = append(words, l.words...)
	words = append(words, other.words...)

	return List{
		words: words,
		len:   l.len + other.len,
	}
}