package gen

import (
	"git.codemonkeysoftware.net/b/peachy-go/csexp"
	"pgregory.net/rapid"
)

type T rapid.TB

func Atom() *rapid.Generator[csexp.Atom] {
	return rapid.Custom(func(t *rapid.T) csexp.Atom {
		return csexp.Atom(rapid.SliceOf(rapid.Byte()).Draw(t, "atom"))
	})
}

func List() *rapid.Generator[csexp.List] {
	return rapid.Custom(func(t *rapid.T) csexp.List {
		var s []csexp.Sexp = rapid.SliceOfN(rapid.Deferred(Sexp), 0, 5).Draw(t, "s")
		return csexp.List(s)
	})
}

func AsSexp[T csexp.Sexp](value T) csexp.Sexp {
	return csexp.Sexp(value)
}

func Sexp() *rapid.Generator[csexp.Sexp] {
	return rapid.Custom(func(t *rapid.T) csexp.Sexp {
		choice := rapid.Uint8Range(0, 10).Draw(t, "choice")
		// If we don't weight it enough towards atoms, it likes to overflow the stack.
		if choice < 7 {
			return rapid.Map(Atom(), AsSexp).Draw(t, "atom-sexp")
		}
		return rapid.Map(rapid.Deferred(List), AsSexp).Draw(t, "list-sexp")
	})
}
