package config

import (
	"net"
	"os"
	"path/filepath"
)

const (
	ClientPort = ":8100"
	FilePort   = ":8120"
)

func GetStoryFilepath() string {
	return getFilepath("STORY_FILENAME", "data/story/story.json")
}

func GetDBFilepath() string {
	return getFilepath("DB_FILENAME", "data/db/store.db")
}

func GetHost() string {
	host := os.Getenv("HOST")
	if host != "" {
		return host
	}
	ips, err := getLocalIPs()
	if err != nil || len(ips) == 0 {
		return "http://127.0.0.1" + ClientPort
	}
	return "http://" + ips[0] + ClientPort
}

func GetFileHost() string {
	host := os.Getenv("FILE_HOST")
	if host != "" {
		return host
	}
	ips, err := getLocalIPs()
	if err != nil || len(ips) == 0 {
		return "http://127.0.0.1" + FilePort
	}
	return "http://" + ips[0] + FilePort
}

func getFilepath(env string, defaultFilepath string) string {
	filepath := selectFilepath(env, defaultFilepath)
	ensureDirExists(filepath)
	return filepath
}

func selectFilepath(env string, defaultFilepath string) string {
	filepath := os.Getenv(env)
	if filepath != "" {
		return filepath
	}
	return defaultFilepath
}

func ensureDirExists(filePath string) error {
	dir := filepath.Dir(filePath)
	if dir == "" || dir == "." || dir == "/" {
		return nil
	}
	return os.MkdirAll(dir, 0755)
}

func getLocalIPs() ([]string, error) {
	var ips []string
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return nil, err
	}

	for _, addr := range addrs {
		ipNet, ok := addr.(*net.IPNet)
		if !ok {
			continue
		}

		ip := ipNet.IP
		if ip.IsLoopback() || ip.IsLinkLocalMulticast() || ip.IsLinkLocalUnicast() {
			continue
		}

		if ipv4 := ip.To4(); ipv4 != nil {
			ips = append(ips, ipv4.String())
		}
	}

	return ips, nil
}
