package adbembed

import (
	"embed"
	"fmt"
	"os"
	"path/filepath"
	"runtime"
)

//go:embed all:bin
var binFS embed.FS

// Resolve returns the path to a usable adb binary.
// Order: embedded binary → ANDROID_HOME → PATH.
func Resolve() (string, error) {
	if path, err := extractEmbedded(); err == nil {
		return path, nil
	}
	return findOnSystem()
}

func extractEmbedded() (string, error) {
	name := embeddedName()
	data, err := binFS.ReadFile("bin/" + name)
	if err != nil || len(data) < 1024 {
		return "", fmt.Errorf("no embedded binary")
	}

	cacheDir, err := os.UserCacheDir()
	if err != nil {
		return "", err
	}
	dir := filepath.Join(cacheDir, "droidscope", "adb")
	if err := os.MkdirAll(dir, 0755); err != nil {
		return "", err
	}

	dest := filepath.Join(dir, adbExeName())
	if err := os.WriteFile(dest, data, 0755); err != nil {
		return "", err
	}
	return dest, nil
}

func findOnSystem() (string, error) {
	if home := os.Getenv("ANDROID_HOME"); home != "" {
		candidate := filepath.Join(home, "platform-tools", adbExeName())
		if _, err := os.Stat(candidate); err == nil {
			return candidate, nil
		}
	}
	// Fall back to PATH
	return findInPath()
}

func embeddedName() string {
	os_ := runtime.GOOS
	arch := runtime.GOARCH
	if os_ == "windows" {
		return fmt.Sprintf("adb-%s-%s.exe", os_, arch)
	}
	return fmt.Sprintf("adb-%s-%s", os_, arch)
}

func adbExeName() string {
	if runtime.GOOS == "windows" {
		return "adb.exe"
	}
	return "adb"
}
