package utils

import (
	"log"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestNewPager(t *testing.T) {
	const FALLBACK_PAGER = "more"
	os.Setenv("PAGER", "more")
	devnull, _ := os.Open(os.DevNull)
	defer devnull.Close()
	exec := &Executor{devnull, devnull, log.New(devnull, "", 0)}
	pager := NewPager(exec, FALLBACK_PAGER)
	if pager.cmd != "more" {
		t.Error("NewPager() returned an incorrect command")
	}
	os.Setenv("PAGER", "")
	pager = NewPager(exec, FALLBACK_PAGER)
	if pager.cmd != FALLBACK_PAGER {
		t.Error("NewPager() returned an incorrect command")
	}
	if pager.executor.Stdout != devnull {
		t.Error("NewPager() returned an incorrect stdout")
	}
	if pager.executor.Stderr != devnull {
		t.Error("NewPager() returned an incorrect stderr")
	}
}

func TestRun(t *testing.T) {
	dummyStdout, dummyStderr := strings.Builder{}, strings.Builder{}
	devnull, _ := os.Open(os.DevNull)
	defer devnull.Close()
	logger := log.New(devnull, "", 0)
	executor := Executor{&dummyStdout, &dummyStderr, logger}
	err := executor.Run("echo foo")
	if err != nil {
		t.Error("Run() returned an error")
	}
	if dummyStdout.String() != "foo\n" {
		t.Error("Run() returned an incorrect stdout")
	}
	if dummyStderr.String() != "" {
		t.Error("Run() returned an incorrect stderr")
	}
}

func TestPanicOnFail(t *testing.T) {
	dummyStdout, dummyStderr := strings.Builder{}, strings.Builder{}
	devnull, _ := os.Open(os.DevNull)
	defer devnull.Close()
	logger := log.New(devnull, "", 0)
	executor := Executor{&dummyStdout, &dummyStderr, logger}
	defer func() {
		if r := recover(); r == nil {
			t.Error("PanicOnFail() did not panic")
		}
	}()
	executor.PanicOnFail("false")
}

func TestDisplay(t *testing.T) {
	dummyStdout, dummyStderr := strings.Builder{}, strings.Builder{}
	devnull, _ := os.Open(os.DevNull)
	defer devnull.Close()
	logger := log.New(devnull, "", 0)
	executor := Executor{&dummyStdout, &dummyStderr, logger}
	pager := NewPager(&executor, "more")
	td := t.TempDir()
	testFile := Content2File(filepath.Join(td, "test.txt"), "foo\nbar")
	pager.Display(testFile)
	if !strings.Contains(dummyStdout.String(), "foo\nbar") {
		t.Error("Display() did not output the expected content")
	}
}
