package cli

import (
	"bufio"
	"bytes"
	"strings"
	"testing"

	"gitlab.com/M0M097/pkg/internal/must"
)

func TestBanner(t *testing.T) {
	got := Banner("Test", "This is a test message", 80)
	want := `
------------------------------------- Test -------------------------------------
This is a test message
--------------------------------------------------------------------------------`
	if got != want {
		t.Errorf("Banner() = %q, want %q", got, want)
	} else {
		t.Log("Banner() test passed with output:", got)
	}
}

func TestWrapLine(t *testing.T) {
	tests := []struct {
		name string
		in   string
		want string
	}{
		{
			name: "wraps at previous space",
			in:   "alpha beta gamma",
			want: "alpha beta\ngamma",
		},
		{
			name: "wraps at next space for long word",
			in:   "supercalifragilistic word",
			want: "supercali\nragilistic\nword",
		},
		{
			name: "leaves long word without spaces",
			in:   "supercalifragilistic",
			want: "supercalifragilistic",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := WrapLine(tt.in, 10); got != tt.want {
				t.Fatalf("WrapLine() = %q, want %q", got, tt.want)
			}
		})
	}
}

func TestStripCommentsAndTokenize(t *testing.T) {
	input := "foo bar # baz\nqux"
	tokens := StripCommentsAndTokenize(strings.NewReader(input))
	if len(tokens) != 3 {
		t.Error("StripCommentsAndTokenize() returned an incorrect number of tokens")
	}
	if tokens[0] != "foo" || tokens[1] != "bar" || tokens[2] != "qux" {
		t.Error("StripCommentsAndTokenize() returned incorrect tokens")
	}
	t.Log("StripCommentsAndTokenize() test passed with tokens:", tokens)
}

func TestPromptUser(t *testing.T) {
	in := strings.NewReader("foo\n")
	var out bytes.Buffer
	buf := bufio.NewWriter(&out)
	prompt := "bar"
	res := PromptUser(buf, in, prompt)
	buf.Flush()
	if out.String() != prompt+" [y/N]: " {
		t.Error("PromptUser() did not write the correct prompt")
	}
	if res {
		t.Error("PromptUser() returned true for 'foo'")
	}
	if !PromptUser(buf, strings.NewReader("y\n"), prompt) {
		t.Error("PromptUser() returned false for 'y'")
	}
	if !PromptUser(buf, strings.NewReader("Y\n"), prompt) {
		t.Error("PromptUser() returned false for 'Y'")
	}
	r := strings.NewReader("N\nT")
	PromptUser(buf, r, prompt)
	if must.ReadChar(r) != 'T' {
		t.Error("Newline not correctly consumed")
	}
}
