package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"

	"gopkg.in/yaml.v3"
)

type NetDevConfig map[string]interface{}
type ContainerConfig map[string]interface{}
type VolumeConfig map[string]interface{}

type YamlTopology struct {
	Devices    []NetDevConfig    `yaml:"devices"`
	Containers []ContainerConfig `yaml:"containers"`
	Volumes    []VolumeConfig    `yaml:"volumes"`
}

func AddAddress(device, address, ns string) error {
	c := []string{"ip", "addr", "add", address, "dev", device}
	cmd := appendNetns(c, ns)
	err := cmd.Run()
	if err != nil {
		return fmt.Errorf("failed to set ip address for %s: %v", device, err)
	}
	return nil
}

func convertToNetConfig(t *YamlTopology) (*NetTopology, error) {
	var topology NetTopology
	for _, dev := range t.Devices {
		topology = append(topology, NewNetConfig(dev))
	}
	return &topology, nil
}

func loadTopoFile(topoName string) (*NetTopology, error) {
	var yamlTopo YamlTopology

	data, err := ioutil.ReadFile(topoName)
	if err != nil {
		return nil, fmt.Errorf("read error: %v", err)
	}

	err = yaml.Unmarshal(data, &yamlTopo)
	if err != nil {
		return nil, fmt.Errorf("error parsing topology data: %v", err)
	}

	return convertToNetConfig(&yamlTopo)
}

func LoadTopology(path, topoName string) (*NetTopology, error) {
	dir, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer dir.Close()

	files, err := dir.Readdir(0)
	if err != nil {
		return nil, err
	}

	for i := range files {
		file := files[i]
		fileName := file.Name()

		// cut off file extension
		f := strings.Split(fileName, ".")[0]
		if f == topoName {
			return loadTopoFile(path + fileName)
		}
	}
	return nil, fmt.Errorf("topology '%s' not found", topoName)
}
