package runtimeenv

import (
	"fmt"
	"os"
	"strings"
)

type Mode string

const (
	ModeAuto   Mode = "auto"
	ModeLocal  Mode = "local"
	ModeLiveCD Mode = "livecd"
)

type Info struct {
	Mode     Mode
	Detected bool
	Reason   string
}

func ParseMode(raw string) (Mode, error) {
	mode := Mode(strings.TrimSpace(strings.ToLower(raw)))
	switch mode {
	case "", ModeAuto:
		return ModeAuto, nil
	case ModeLocal, ModeLiveCD:
		return mode, nil
	default:
		return "", fmt.Errorf("invalid runtime %q — use auto, local, or livecd", raw)
	}
}

func Detect(flagValue string) (Info, error) {
	flagMode, err := ParseMode(flagValue)
	if err != nil {
		return Info{}, err
	}
	if flagMode != ModeAuto {
		return Info{Mode: flagMode, Reason: "flag"}, nil
	}

	if envMode, ok := getenvMode("BEE_RUNTIME"); ok {
		return Info{Mode: envMode, Reason: "env:BEE_RUNTIME"}, nil
	}

	if fileExists("/etc/bee-release") {
		return Info{Mode: ModeLiveCD, Detected: true, Reason: "marker:/etc/bee-release"}, nil
	}

	if data, err := os.ReadFile("/proc/cmdline"); err == nil {
		cmdline := string(data)
		if strings.Contains(cmdline, " boot=live") || strings.HasPrefix(cmdline, "boot=live ") || strings.Contains(cmdline, "live-media") {
			return Info{Mode: ModeLiveCD, Detected: true, Reason: "kernel:boot=live"}, nil
		}
	}

	return Info{Mode: ModeLocal, Detected: true, Reason: "default:local"}, nil
}

func getenvMode(name string) (Mode, bool) {
	value := strings.TrimSpace(os.Getenv(name))
	if value == "" {
		return "", false
	}
	mode, err := ParseMode(value)
	if err != nil || mode == ModeAuto {
		return "", false
	}
	return mode, true
}

func fileExists(path string) bool {
	info, err := os.Stat(path)
	return err == nil && !info.IsDir()
}
