package main

import (
	"bufio"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

// wayfarerEnvVar — имя переменной в .env, которой можно поменять
// сид генерации всей галактики Странника (пасхалка в духе
// оригинальной Elite, где числа генератора можно было поменять
// прямо в исходном коде игры — здесь то же самое, но без правки
// кода коллекции).
const wayfarerEnvVar = "WAYFARER_GALAXY_SEED"

// loadWayfarerGalaxySeed ищет файл .env сначала рядом с исполняемым
// файлом программы, затем (если там не нашёлся или не удалось
// определить путь к исполняемому файлу — так бывает, например, при
// запуске через "go run .") в текущей рабочей директории. Если ни
// там, ни там подходящей строки нет — сид остаётся нулевым
// (стандартная галактика, поведение не меняется).
func loadWayfarerGalaxySeed() {
	for _, dir := range wayfarerEnvSearchDirs() {
		if seed, ok := readWayfarerSeedFromEnvFile(filepath.Join(dir, ".env")); ok {
			wayfarerGalaxySeed = seed
			return
		}
	}
}

func wayfarerEnvSearchDirs() []string {
	var dirs []string
	if exe, err := os.Executable(); err == nil {
		dirs = append(dirs, filepath.Dir(exe))
	}
	if cwd, err := os.Getwd(); err == nil {
		dirs = append(dirs, cwd)
	}
	return dirs
}

// readWayfarerSeedFromEnvFile читает path и ищет в нём строку вида
// WAYFARER_GALAXY_SEED=<число> (пробелы вокруг "=" и в начале/конце
// значения игнорируются; строки-комментарии, начинающиеся с "#", и
// пустые строки пропускаются). Возвращает (0, false), если файла нет,
// его не удалось прочитать, либо в нём нет такой переменной или её
// значение не является целым числом.
func readWayfarerSeedFromEnvFile(path string) (uint64, bool) {
	f, err := os.Open(path)
	if err != nil {
		return 0, false
	}
	defer f.Close()

	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		key, value, found := strings.Cut(line, "=")
		if !found || strings.TrimSpace(key) != wayfarerEnvVar {
			continue
		}
		value = strings.TrimSpace(value)
		value = strings.Trim(value, `"'`)
		n, err := strconv.ParseInt(value, 10, 64)
		if err != nil {
			return 0, false
		}
		return uint64(n), true
	}
	return 0, false
}
