package recipe

import (
	"path"
	"testing"

	"coopcloud.tech/abra/pkg/config"
	"coopcloud.tech/abra/pkg/test"

	"github.com/google/go-cmp/cmp"
	"github.com/stretchr/testify/assert"
)

func TestGet(t *testing.T) {
	cfg := config.LoadAbraConfig()
	testcases := []struct {
		name   string
		recipe Recipe
	}{
		{
			name: "foo",
			recipe: Recipe{
				Name:          "foo",
				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/foo"),
				GitURL:        "https://git.coopcloud.tech/coop-cloud/foo.git",
				SSHURL:        "ssh://git@git.coopcloud.tech:2222/coop-cloud/foo.git",
				ComposePath:   path.Join(cfg.GetAbraDir(), "recipes/foo/compose.yml"),
				ReadmePath:    path.Join(cfg.GetAbraDir(), "recipes/foo/README.md"),
				SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/foo/.env.sample"),
				AbraShPath:    path.Join(cfg.GetAbraDir(), "recipes/foo/abra.sh"),
			},
		},
		{
			name: "foo:1.2.3",
			recipe: Recipe{
				Name:          "foo",
				EnvVersion:    "1.2.3",
				EnvVersionRaw: "1.2.3",
				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/foo"),
				GitURL:        "https://git.coopcloud.tech/coop-cloud/foo.git",
				SSHURL:        "ssh://git@git.coopcloud.tech:2222/coop-cloud/foo.git",
				ComposePath:   path.Join(cfg.GetAbraDir(), "recipes/foo/compose.yml"),
				ReadmePath:    path.Join(cfg.GetAbraDir(), "recipes/foo/README.md"),
				SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/foo/.env.sample"),
				AbraShPath:    path.Join(cfg.GetAbraDir(), "recipes/foo/abra.sh"),
			},
		},
		{
			name: "mygit.org/myorg/cool-recipe",
			recipe: Recipe{
				Name:          "mygit.org/myorg/cool-recipe",
				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"),
				GitURL:        "https://mygit.org/myorg/cool-recipe.git",
				SSHURL:        "ssh://git@mygit.org/myorg/cool-recipe.git",
				ComposePath:   path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/compose.yml"),
				ReadmePath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/README.md"),
				SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/.env.sample"),
				AbraShPath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"),
			},
		},
		{
			name: "mygit.org/myorg/cool-recipe:1.2.4",
			recipe: Recipe{
				Name:          "mygit.org/myorg/cool-recipe",
				EnvVersion:    "1.2.4",
				EnvVersionRaw: "1.2.4",
				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"),
				GitURL:        "https://mygit.org/myorg/cool-recipe.git",
				SSHURL:        "ssh://git@mygit.org/myorg/cool-recipe.git",
				ComposePath:   path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/compose.yml"),
				ReadmePath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/README.md"),
				SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/.env.sample"),
				AbraShPath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"),
			},
		},
		{
			name: "mygit.org/myorg/cool-recipe:1e83340e+U",
			recipe: Recipe{
				Name:          "mygit.org/myorg/cool-recipe",
				EnvVersion:    "1e83340e",
				EnvVersionRaw: "1e83340e+U",
				Dir:           path.Join(cfg.GetAbraDir(), "/recipes/mygit_org_myorg_cool-recipe"),
				GitURL:        "https://mygit.org/myorg/cool-recipe.git",
				SSHURL:        "ssh://git@mygit.org/myorg/cool-recipe.git",
				ComposePath:   path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/compose.yml"),
				ReadmePath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/README.md"),
				SampleEnvPath: path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/.env.sample"),
				AbraShPath:    path.Join(cfg.GetAbraDir(), "recipes/mygit_org_myorg_cool-recipe/abra.sh"),
			},
		},
	}

	for _, tc := range testcases {
		t.Run(tc.name, func(t *testing.T) {
			t.Setenv("ABRA_DIR", "<abraDir>")
			recipe := Get(tc.name)
			if diff := cmp.Diff(tc.recipe, recipe); diff != "" {
				t.Errorf("Recipe mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestGetVersionLabelLocalDoesNotUseTimeoutLabel(t *testing.T) {
	test.Setup()
	t.Cleanup(func() { test.Teardown() })

	r := Get(test.RecipeName)
	if err := r.EnsureExists(); err != nil {
		t.Fatal(err)
	}

	timeout := "120"
	if err := test.AddEnv("TIMEOUT", timeout); err != nil {
		t.Fatal(err)
	}

	for i := 1; i < 3; i++ {
		label, err := r.GetVersionLabelLocal()
		if err != nil {
			t.Fatal(err)
		}
		assert.NotEqual(t, label, timeout)
	}
}
