/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/

package inject

import (
	"bytes"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestRender(t *testing.T) {
	testCases := map[string]struct {
		modifier     func(vals *PinningValues)
		wantTemplate string
		wantErr      bool
	}{
		"valid": {
			wantTemplate: `package foo

// Code generated by oci-pin. DO NOT EDIT.

const (
	// barServiceRegistry is the bar-service container image registry.
	barServiceRegistry = "registry.example.com"

	// barServicePrefix is the bar-service container image prefix.
	barServicePrefix = "staging"

	// barServiceName is the bar-service container image short name part.
	barServiceName = "bar-service"

	// barServiceTag is the tag for the bar-service container image.
	barServiceTag = "v1.2.3"

	// barServiceDigest is the digest for the bar-service container image.
	barServiceDigest = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
)
`,
			wantErr: false,
		},
		"valid without prefix": {
			modifier: func(vals *PinningValues) {
				vals.Prefix = ""
			},
			wantTemplate: `package foo

// Code generated by oci-pin. DO NOT EDIT.

const (
	// barServiceRegistry is the bar-service container image registry.
	barServiceRegistry = "registry.example.com"

	// barServiceName is the bar-service container image short name part.
	barServiceName = "bar-service"

	// barServiceTag is the tag for the bar-service container image.
	barServiceTag = "v1.2.3"

	// barServiceDigest is the digest for the bar-service container image.
	barServiceDigest = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
)
`,
			wantErr: false,
		},
		"valid without tag": {
			modifier: func(vals *PinningValues) {
				vals.Tag = ""
			},
			wantTemplate: `package foo

// Code generated by oci-pin. DO NOT EDIT.

const (
	// barServiceRegistry is the bar-service container image registry.
	barServiceRegistry = "registry.example.com"

	// barServicePrefix is the bar-service container image prefix.
	barServicePrefix = "staging"

	// barServiceName is the bar-service container image short name part.
	barServiceName = "bar-service"

	// barServiceDigest is the digest for the bar-service container image.
	barServiceDigest = "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
)
`,
			wantErr: false,
		},
		"missing package": {
			modifier: func(vals *PinningValues) {
				vals.Package = ""
			},
			wantErr: true,
		},
		"missing ident": {
			modifier: func(vals *PinningValues) {
				vals.Ident = ""
			},
			wantErr: true,
		},
		"missing registry": {
			modifier: func(vals *PinningValues) {
				vals.Registry = ""
			},
			wantErr: true,
		},
		"missing name": {
			modifier: func(vals *PinningValues) {
				vals.Name = ""
			},
			wantErr: true,
		},
		"missing digest": {
			modifier: func(vals *PinningValues) {
				vals.Digest = ""
			},
			wantErr: true,
		},
		"malformed package": {
			modifier: func(vals *PinningValues) {
				vals.Package = "foo bar"
			},
			wantErr: true,
		},
		"malformed ident": {
			modifier: func(vals *PinningValues) {
				vals.Ident = "foo bar"
			},
			wantErr: true,
		},
		"malformed registry": {
			modifier: func(vals *PinningValues) {
				vals.Registry = "\n"
			},
			wantErr: true,
		},
		"malformed prefix": {
			modifier: func(vals *PinningValues) {
				vals.Prefix = "\n"
			},
			wantErr: true,
		},
		"malformed name": {
			modifier: func(vals *PinningValues) {
				vals.Name = "foo bar"
			},
			wantErr: true,
		},
		"malformed tag": {
			modifier: func(vals *PinningValues) {
				vals.Tag = `"`
			},
			wantErr: true,
		},
		"malformed digest": {
			modifier: func(vals *PinningValues) {
				vals.Digest = "foo bar"
			},
			wantErr: true,
		},
	}

	for name, tc := range testCases {
		t.Run(name, func(t *testing.T) {
			assert := assert.New(t)
			require := require.New(t)

			vals := defaultPinningValues()

			if tc.modifier != nil {
				tc.modifier(vals)
			}

			var buf bytes.Buffer
			err := Render(&buf, *vals)
			if tc.wantErr {
				require.Error(err)
				return
			}
			require.NoError(err)
			assert.Equal(tc.wantTemplate, buf.String())
		})
	}
}

func defaultPinningValues() *PinningValues {
	return &PinningValues{
		Package:  "foo",
		Ident:    "barService",
		Registry: "registry.example.com",
		Prefix:   "staging",
		Name:     "bar-service",
		Tag:      "v1.2.3",
		Digest:   "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
	}
}