// SPDX-FileCopyrightText: 2021 Luke Granger-Brown <depot@lukegb.com>
//
// SPDX-License-Identifier: Apache-2.0

package fngen_test

import (
	"context"
	"fmt"
	"strings"
	"testing"

	"hg.lukegb.com/lukegb/depot/web/fup/fuphttp/fngen"
)

func TestIdentityGenerator(t *testing.T) {
	fallback := func(filenamePrefix string, filenameExt string, attempt int) string {
		return fmt.Sprintf("prefix=%s; ext=%s; attempt=%d", filenamePrefix, filenameExt, attempt)
	}

	gen := fngen.IdentityGenerator(fallback)

	if got, want := gen("prefix", ".ext", 0), "prefix.ext"; got != want {
		t.Errorf("IdentityGenerator with 0 attempts = %q; want %q", got, want)
	}
	if got, want := gen("prefix", ".ext", 1), "prefix=prefix; ext=.ext; attempt=0"; got != want {
		t.Errorf("IdentityGenerator with 1 attempt = %q; want %q", got, want)
	}
	if got, want := gen("prefix", ".ext", 2), "prefix=prefix; ext=.ext; attempt=1"; got != want {
		t.Errorf("IdentityGenerator with 2 attempts = %q; want %q", got, want)
	}

	if got, want := gen("prefix", "", 0), "prefix"; got != want {
		t.Errorf("IdentityGenerator with no extension = %q; want %q", got, want)
	}
}

func TestPetnameGenerator(t *testing.T) {
	got := fngen.PetnameGenerator("prefix", ".ext", 0)
	if !strings.HasSuffix(got, ".ext") {
		t.Errorf("PetnameGenerator(%q, %q, 0) = %q; want something ending in %v", "prefix", ".ext", got, ".ext")
	}
}

func TestBoringGenerator(t *testing.T) {
	got := fngen.BoringGenerator("prefix", ".ext", 0)
	if !strings.HasSuffix(got, ".ext") {
		t.Errorf("BoringGenerator(%q, %q, 0) = %q; want something ending in %v", "prefix", ".ext", got, ".ext")
	}
}

func TestUniqueName(t *testing.T) {
	gen := func(filenamePrefix string, filenameExt string, attempt int) string {
		return fmt.Sprintf("%s.%d%s", filenamePrefix, attempt, filenameExt)
	}
	exists := func(ctx context.Context, name string) (bool, error) {
		switch name {
		case "firstTry.0.txt":
			return false, nil
		case "secondTry.0.txt":
			return true, nil
		case "secondTry.1.txt":
			return false, nil
		default:
			return false, fmt.Errorf("no existence recorded for %q for testing", name)
		}
	}

	ctx := context.Background()
	tcs := []struct {
		prefix  string
		want    string
		wantErr bool
	}{{
		prefix: "firstTry",
		want:   "firstTry.0.txt",
	}, {
		prefix: "secondTry",
		want:   "secondTry.1.txt",
	}, {
		prefix:  "error",
		wantErr: true,
	}}
	for _, tc := range tcs {
		got, err := fngen.UniqueName(ctx, exists, tc.prefix, ".txt", gen)
		switch {
		case err != nil && !tc.wantErr:
			t.Errorf("UniqueName(%q): %v", tc.prefix, err)
		case err == nil && tc.wantErr:
			t.Errorf("UniqueName(%q) didn't return error; expected one", tc.prefix)
		}
		if got != tc.want {
			t.Errorf("UniqueName(%q) = %q; want %q", tc.prefix, got, tc.want)
		}
	}
}