package main

import (
	"encoding/binary"
	"log"
	"net"
	"os"
	"strings"
	"sync"

	"gopkg.in/yaml.v3"
)

type Node struct {
	Real string `yaml:"real"`
	Virt string `yaml:"virt"`
}

type Config struct {
	Network struct {
		Self  Node   `yaml:"self"`
		Nodes []Node `yaml:"nodes"`
	} `yaml:"network"`

	IPv4Nodes map[uint32]string
	lock      sync.Mutex
}

var config = NewConfig()

func NewConfig() *Config {
	cnf := &Config{IPv4Nodes: make(map[uint32]string)}
	f, err := os.Open("config.yaml")
	if err != nil {
		log.Panic(err)
	}
	dec := yaml.NewDecoder(f)
	err = dec.Decode(cnf)
	if err != nil {
		log.Panic(err)
	}

	for _, node := range cnf.Network.Nodes {
		values := strings.Split(node.Virt, "/")
		if len(values) != 2 {
			log.Panic("virt must have '/'. eg 1.1.1.1/24")
		}
		inet, net, err := net.ParseCIDR(node.Virt)
		if err != nil {
			log.Panic(err)
		}

		cnf.IPv4Nodes[binary.LittleEndian.Uint32([]byte(inet))] = node.Real
		log.Printf("real %v virt %v %v", node.Real, inet, net)
	}

	return cnf
}

func (cnf *Config) Lock(do func()) {
	cnf.lock.Lock()
	defer cnf.lock.Unlock()
	do()
}