package version

import (
	"testing"

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

func TestVersion_NewVersion(t *testing.T) {
	tests := []struct {
		name          string
		version       string
		expectedMajor uint64
		expectedMinor uint64
		expectedPatch uint64
		expectedIsPre bool
	}{
		{
			name:          "valid version",
			version:       "v1.2.3",
			expectedMajor: 1,
			expectedMinor: 2,
			expectedPatch: 3,
			expectedIsPre: false,
		},
		{
			name:          "valid version without leading v",
			version:       "1.2.3",
			expectedMajor: 1,
			expectedMinor: 2,
			expectedPatch: 3,
			expectedIsPre: false,
		},
		{
			name:          "valid version with pre component",
			version:       "v1.2.3-rc1",
			expectedMajor: 1,
			expectedMinor: 2,
			expectedPatch: 3,
			expectedIsPre: true,
		},
		{
			name:          "valid version with post component (currently not parsed)",
			version:       "v1.2.3+builddata",
			expectedMajor: 1,
			expectedMinor: 2,
			expectedPatch: 3,
			expectedIsPre: false,
		},
		{
			name:          "valid version with extensions",
			version:       "v1.2.3-rc1+builddata",
			expectedMajor: 1,
			expectedMinor: 2,
			expectedPatch: 3,
			expectedIsPre: true,
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			actualVersion, err := NewVersion(tc.version)
			require.NoError(t, err)

			assert.Equal(t, tc.expectedMajor, actualVersion.Major)
			assert.Equal(t, tc.expectedMinor, actualVersion.Minor)
			assert.Equal(t, tc.expectedPatch, actualVersion.Patch)
			assert.Equal(t, tc.expectedIsPre, actualVersion.IsPre)
		})
	}
}

func TestVersion_NewVersion_Error(t *testing.T) {
	tests := []struct {
		name    string
		version string
	}{
		{
			name:    "empty version",
			version: "",
		},
		{
			name:    "invalid version",
			version: "invalid.version",
		},
		{
			name:    "invalid major",
			version: "vA.1.2",
		},
		{
			name:    "invalid minor",
			version: "v1.A.2",
		},
		{
			name:    "invalid patch",
			version: "v1.2.A",
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			_, err := NewVersion(tc.version)
			require.Error(t, err)
		})
	}
}
