//go:build !integration

package helperimage

import (
	"fmt"
	"runtime"
	"testing"

	"github.com/stretchr/testify/assert"

	"gitlab.com/gitlab-org/gitlab-runner/shells"
)

func Test_linuxInfo_create(t *testing.T) {
	for _, shell := range []string{"sh", "bash", shells.SNPwsh} {
		expectedTagSuffix := ""
		expectedCmd := bashCmd
		if shell == shells.SNPwsh {
			expectedTagSuffix = "-pwsh"
			expectedCmd = getPowerShellCmd(shell)
		}

		tests := map[string]struct {
			shell        string
			dockerArch   string
			revision     string
			flavor       string
			expectedInfo Info
		}{
			"When dockerArch not specified we fallback to runtime arch": {
				shell:      shell,
				dockerArch: "",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: getExpectedArch(),
					Name:         GitLabRegistryName,
					Tag:          fmt.Sprintf("%s-2923a43%s", getExpectedArch(), expectedTagSuffix),
					Prebuilt:     "prebuilt-alpine-" + getExpectedArch() + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Docker runs on armv6l": {
				shell:      shell,
				dockerArch: "armv6l",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "arm",
					Name:         GitLabRegistryName,
					Tag:          "arm-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-arm" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Docker runs on amd64": {
				shell:      shell,
				dockerArch: "amd64",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "x86_64",
					Name:         GitLabRegistryName,
					Tag:          "x86_64-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-x86_64" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Docker runs on arm64": {
				shell:      shell,
				dockerArch: "aarch64",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "arm64",
					Name:         GitLabRegistryName,
					Tag:          "arm64-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-arm64" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Docker runs on s390x": {
				shell:      shell,
				dockerArch: "s390x",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "s390x",
					Name:         GitLabRegistryName,
					Tag:          "s390x-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-s390x" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Docker runs on ppc64le": {
				shell:      shell,
				dockerArch: "ppc64le",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "ppc64le",
					Name:         GitLabRegistryName,
					Tag:          "ppc64le-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-ppc64le" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Docker runs on riscv64, with a default of alpine-edge": {
				shell:      shell,
				dockerArch: "riscv64",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "riscv64",
					Name:         GitLabRegistryName,
					Tag:          "alpine-edge-riscv64-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-edge-riscv64" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Configured architecture is unknown": {
				shell:      shell,
				dockerArch: "some-random-arch",
				revision:   "2923a43",
				expectedInfo: Info{
					Architecture: "some-random-arch",
					Name:         GitLabRegistryName,
					Tag:          "some-random-arch-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-alpine-some-random-arch" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
			"Flavor configured default registry": {
				dockerArch: "amd64",
				revision:   "2923a43",
				flavor:     "ubuntu",
				expectedInfo: Info{
					Architecture: "x86_64",
					Name:         GitLabRegistryName,
					Tag:          "ubuntu-x86_64-2923a43" + expectedTagSuffix,
					Prebuilt:     "prebuilt-ubuntu-x86_64" + expectedTagSuffix,
					Cmd:          expectedCmd,
				},
			},
		}

		t.Run(shell, func(t *testing.T) {
			for name, test := range tests {
				t.Run(name, func(t *testing.T) {
					l := new(linuxInfo)

					image, err := l.Create(
						test.revision,
						Config{
							Architecture: test.dockerArch,
							Shell:        shell,
							Flavor:       test.flavor,
						},
					)

					assert.NoError(t, err)
					assert.Equal(t, test.expectedInfo, image)
				})
			}
		})
	}
}

// We re write amd64 to x86_64 for the helper image, and we don't want this test
// to be runtime dependant.
func getExpectedArch() string {
	if runtime.GOARCH == "amd64" {
		return "x86_64"
	}

	return runtime.GOARCH
}
