package internal

import (
	"os"
	"testing"

	"github.com/bazelbuild/rules_go/go/tools/bazel"
	"github.com/stretchr/testify/assert"

	"edge-infra.dev/pkg/lib/build/git"
	"edge-infra.dev/pkg/lib/cli/sh"
)

func TestParseBuildInfo(t *testing.T) {
	// set up test git repo for inference
	dir := bazel.TestTmpDir()
	defer os.RemoveAll(dir)

	repo := createTestGitRepo(t, dir)
	assert.NoError(t, os.Chdir(repo))

	g := git.NewInDir(repo)
	commit, err := g.Commit()
	assert.NoError(t, err)
	timestamp, err := g.Timestamp()
	assert.NoError(t, err)

	tcs := map[string]struct {
		packer Packer
		valid  bool
	}{
		"valid": {
			Packer{
				rc:       true,
				version:  "7.7.7",
				source:   "https://github.com/ncrvoyix-swt-retail/edge-infra",
				revision: commit,
				created:  timestamp.Unix(),
			},
			true,
		},
		// invalid components per pkg/f8n/warehouse/oci/validate
		// expected errors taken from pkg/f8n/warehouse/oci/validate
		"invalid version": {
			Packer{
				rc:       true,
				version:  "abcde",
				source:   "https://github.com/ncrvoyix-swt-retail/edge-infra",
				revision: commit,
				created:  timestamp.Unix(),
			},
			false,
		},
		"invalid source": {
			Packer{
				rc:       true,
				version:  "7.7.7",
				source:   "not-a-real-url",
				revision: commit,
				created:  timestamp.Unix(),
			},
			false,
		},
		"invalid revision": {
			Packer{
				rc:       true,
				version:  "7.7.7",
				source:   "https://github.com/ncrvoyix-swt-retail/edge-infra",
				revision: "!#$%@#$%&*()",
				created:  timestamp.Unix(),
			},
			false,
		},
		"negative created time handled as 0": {
			Packer{
				rc:       true,
				version:  "7.7.7",
				source:   "https://github.com/ncrvoyix-swt-retail/edge-infra",
				revision: commit,
				created:  -1,
			},
			true,
		},
		"multiple invalid components": {
			Packer{
				rc:       true,
				version:  "abcde",
				source:   "not-a-real-url",
				revision: commit,
				created:  0,
			},
			false,
		},
		// invalid components per pkg/lib/build
		// expected errors taken from pkg/lib/build
		"revision is too short": {
			Packer{
				rc:       true,
				version:  "7.7.7",
				source:   "https://github.com/ncrvoyix-swt-retail/edge-infra",
				revision: "1",
				created:  timestamp.Unix(),
			},
			false,
		},
		// missing components to be inferred by git repo
		"missing components are inferred": {
			Packer{
				rc:      true,
				version: "7.7.7",
			},
			true,
		},
	}

	for test, tc := range tcs {
		t.Run(test, func(t *testing.T) {
			buildInfo, err := tc.packer.parseBuildInfo()
			switch tc.valid {
			case true:
				assert.NoError(t, err)
				assert.NotEmpty(t, buildInfo)
			case false:
				assert.Error(t, err)
				assert.Empty(t, buildInfo)
			}
		})
	}
}

func createTestGitRepo(t *testing.T, dir string) string {
	t.Helper()

	repo, err := os.MkdirTemp(dir, "git_test-*")
	assert.NoError(t, err)
	t.Log("test repo dir", repo)

	shell := sh.NewInDir(repo)
	for _, c := range []string{
		"git init -q",
		"git config user.name \"testbot\"",
		"git config user.email \"testmail@testworld.co\"",
		"git checkout -b test",
		// remote ssh url added to test conversion to https
		"git remote add origin git@github.com:testworld",
		"git commit --allow-empty -m \"\"",
	} {
		assert.NoError(t, shell.RunE(c))
	}

	return repo
}