package main

import (
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"
)

type config struct {
	APIURL     string
	ProductKey string
	LicenseKey string
	ServerIP   string
}

type apiResponse struct {
	Status  string `json:"status"`
	Valid   bool   `json:"valid"`
	Message string `json:"message"`
	Data    struct {
		ProductKey string `json:"product_key"`
		LicenseKey string `json:"license_key"`
		IP         string `json:"ip"`
		ExpiresAt  string `json:"expires_at"`
	} `json:"data"`
}

func main() {
	cfg, err := loadConfig("/etc/internaldemo/license.env")
	if err != nil {
		fmt.Println("config error:", err)
		os.Exit(1)
	}

	if cfg.ServerIP == "" {
		cfg.ServerIP = detectIP()
	}

	if cfg.ServerIP == "" {
		fmt.Println("unable to detect server ip")
		os.Exit(1)
	}

	if err := validate(cfg); err != nil {
		fmt.Println("license check failed:", err)
		os.Exit(1)
	}

	fmt.Println("license check ok")
}

func loadConfig(path string) (config, error) {
	raw, err := os.ReadFile(path)
	if err != nil {
		return config{}, err
	}

	cfg := config{
		APIURL: "https://zwa7f.com/api/client/licenses/validate",
	}

	for _, line := range strings.Split(string(raw), "\n") {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}

		parts := strings.SplitN(line, "=", 2)
		if len(parts) != 2 {
			continue
		}

		key := strings.TrimSpace(parts[0])
		val := strings.Trim(strings.TrimSpace(parts[1]), "\"'")

		switch key {
		case "API_URL":
			cfg.APIURL = val
		case "PRODUCT_KEY":
			cfg.ProductKey = val
		case "LICENSE_KEY":
			cfg.LicenseKey = val
		case "SERVER_IP":
			cfg.ServerIP = val
		}
	}

	return cfg, nil
}

func detectIP() string {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return ""
	}

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

		ip := ipNet.IP.To4()
		if ip != nil {
			return ip.String()
		}
	}

	return ""
}

func validate(cfg config) error {
	query := url.Values{}
	query.Set("product_key", cfg.ProductKey)
	query.Set("license_key", cfg.LicenseKey)
	query.Set("ip", cfg.ServerIP)

	reqURL := cfg.APIURL + "?" + query.Encode()
	client := http.Client{Timeout: 20 * time.Second}

	resp, err := client.Get(reqURL)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var payload apiResponse
	if err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {
		return err
	}

	if !payload.Valid {
		return fmt.Errorf("%s", payload.Message)
	}

	return nil
}
