package engine

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

// seedMarkerFile names the file, in the flat dictionary directory, that records the
// version the directory was first seeded as. It is dot-prefixed so OpenWithVersions'
// version scan skips it (like the .staging upload area).
const seedMarkerFile = ".seed_version"

// resolveSeedVersion returns the version label the flat dictionary directory is
// addressed by, recording it on first use.
//
// The contour's dictionary lives on a named volume seeded from the image once and
// never re-seeded (deploy/docker-compose.yml). The flat DAWGs carry no embedded
// version, so the version a volume was first seeded as is recorded in a
// .seed_version marker and is **authoritative** from then on:
//
//   - fresh directory (no marker): record bootVersion (the build's
//     BACKEND_DICT_VERSION) and return it — the seed of a fresh volume;
//   - already-seeded directory: return the recorded marker and ignore bootVersion.
//
// So a later build seed never relabels the already-seeded flat bytes — which would void
// games pinned to the prior label and mis-serve new ones. The new build version is instead
// delivered as a NEW subdirectory (DeliverVersion) and made active (Service.InitActiveVersion),
// so a redeploy still moves new games to it while old games keep the flat label. New games
// pin the active version (DB-persisted); a console upload can also set it out-of-band.
//
// A directory that cannot be written makes the first record fail; that also breaks
// the admin console (which writes version subdirectories here), so the error is
// returned rather than swallowed, matching the package's fail-loud dictionary setup.
func resolveSeedVersion(dir, bootVersion string) (string, error) {
	path := filepath.Join(dir, seedMarkerFile)
	data, err := os.ReadFile(path)
	if err != nil && !errors.Is(err, os.ErrNotExist) {
		return "", fmt.Errorf("engine: read dictionary seed marker %s: %w", path, err)
	}
	if err == nil {
		if recorded := strings.TrimSpace(string(data)); recorded != "" {
			return recorded, nil
		}
		// An empty/corrupt marker falls through and is rewritten from bootVersion.
	}
	if werr := os.WriteFile(path, []byte(bootVersion+"\n"), 0o644); werr != nil {
		return "", fmt.Errorf("engine: record dictionary seed marker %s: %w", path, werr)
	}
	return bootVersion, nil
}
