package codegen

import (
	"testing"

	"github.com/dave/jennifer/jen"
	"github.com/stretchr/testify/assert"
)

func TestModuleBuilder_Build(t *testing.T) {
	tests := []struct {
		name string
		mb   *ModuleBuilder
		want string
	}{
		{
			name: "empty",
			mb:   Module("Module"),
			want: "// Code generated by actions-generator. DO NOT EDIT.\n\npackage main\n\nfunc New() *Module {\n\treturn &Module{}\n}\n\ntype Module struct{}\n",
		},
		{
			name: "with package name",
			mb:   Module("Module").WithPackageName("test"),
			want: "// Code generated by actions-generator. DO NOT EDIT.\n\npackage test\n\nfunc New() *Module {\n\treturn &Module{}\n}\n\ntype Module struct{}\n",
		},
		{
			name: "with funcs",
			mb:   Module("Module").WithFuncs(Func("test", "string").WithDescription("test description").WithBody(jen.Return(jen.Lit("test")))),
			want: "// Code generated by actions-generator. DO NOT EDIT.\n\npackage main\n\nfunc New() *Module {\n\treturn &Module{}\n}\n\ntype Module struct{}\n\n// test description\nfunc test() string {\n\treturn \"test\"\n}\n",
		},
		{
			name: "with structs",
			mb:   Module("Module").WithStructs(Struct("test")),
			want: "// Code generated by actions-generator. DO NOT EDIT.\n\npackage main\n\nfunc New() *Module {\n\treturn &Module{}\n}\n\ntype Module struct{}\n\ntype test struct{}\n",
		},
		{
			name: "with structs and funcs",
			mb: Module("Module").
				WithStructs(
					Struct("test").WithFuncs(Func("test", "string").WithDescription("test description").WithBody(jen.Return(jen.Lit("test")))),
				).
				WithFuncs(
					Func("test2", "string").WithDescription("test2 description").WithBody(jen.Return(jen.Lit("test"))),
				),
			want: `// Code generated by actions-generator. DO NOT EDIT.

package main

func New() *Module {
	return &Module{}
}

type Module struct{}

type test struct{}

// test description
func (r test) test() string {
	return "test"
}

// test2 description
func test2() string {
	return "test"
}
`,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			assert.Equal(t, tt.want, tt.mb.Build().GoString())
		})
	}
}
