package main

import (
	"errors"
	"fmt"
	"os/exec"
)

type NetType string

const (
	NetNs NetType = "netns"
	Veth          = "veth"
	Tap           = "tap"
)

type NetConfig struct {
	Configure   func() error
	Unconfigure func()
}

type NetTopology []NetConfig

func (t *NetTopology) Configure() error {
	for _, c := range *t {
		err := c.Configure()
		if err != nil {
			return err
		}
	}
	return nil
}

func (t *NetTopology) Unconfigure() {
	for _, c := range *t {
		c.Unconfigure()
	}
}

func newConfigFn(cfg NetDevConfig) func() error {
	t := cfg["type"]
	if t == "netns" {
		return func() error { return AddNetns(cfg["name"].(string)) }
	} else if t == "veth" {
		return func() error {
			var peerNs string
			peer := cfg["peer"].(NetDevConfig)
			peerName := peer["name"].(string)
			err := AddVethPair(cfg["name"].(string), peerName)
			if err != nil {
				return err
			}

			if peer["netns"] != nil {
				peerNs = peer["netns"].(string)
				if peerNs != "" {
					err := LinkSetNetns(peerName, peerNs)
					if err != nil {
						return err
					}
				}
			}
			if peer["ip4"] != nil {
				err = AddAddress(peerName, peer["ip4"].(string), peerNs)
				if err != nil {
					return fmt.Errorf("failed to add configure address for %s: %v", peerName, err)
				}
			}
			return nil
		}
	} else if t == "bridge" {
		return func() error { return configureBridge(cfg) }
	} else if t == "tap" {
		return func() error { return configureTap(cfg) }
	}
	return nil
}

func newUnconfigFn(cfg NetDevConfig) func() {
	t := cfg["type"]
	name := cfg["name"].(string)

	if t == "tap" {
		return func() { DelLink(name) }
	} else if t == "netns" {
		return func() { DelNetns(name) }
	} else if t == "veth" {
		return func() { DelLink(name) }
	} else if t == "bridge" {
		return func() { DelBridge(name, cfg["netns"].(string)) }
	}
	return nil
}

func NewNetConfig(cfg NetDevConfig) NetConfig {
	var nc NetConfig

	nc.Configure = newConfigFn(cfg)
	nc.Unconfigure = newUnconfigFn(cfg)

	return nc
}

func DelBridge(brName, ns string) error {
	err := SetDevDown(brName, ns)
	if err != err {
		return err
	}

	err = addDelBridge(brName, ns, false)
	if err != nil {
		return err
	}

	return nil
}

func configureBridge(dev NetDevConfig) error {
	var ifs []string
	for _, v := range dev["interfaces"].([]interface{}) {
		ifs = append(ifs, v.(string))
	}
	return AddBridge(dev["name"].(string), ifs, dev["netns"].(string))
}

func configureTap(dev NetDevConfig) error {
	return AddTap(dev["name"].(string), dev["ip4"].(string))
}

func SetDevUp(dev, ns string) error {
	return setDevUpDown(dev, ns, true)
}

func SetDevDown(dev, ns string) error {
	return setDevUpDown(dev, ns, false)
}

func AddTap(ifName, ifAddress string) error {
	cmd := exec.Command("ip", "tuntap", "add", ifName, "mode", "tap")
	o, err := cmd.CombinedOutput()
	if err != nil {
		s := fmt.Sprintf("error creating tap %s: %v: %s", ifName, err, string(o))
		return errors.New(s)
	}

	cmd = exec.Command("ip", "addr", "add", ifAddress, "dev", ifName)
	err = cmd.Run()
	if err != nil {
		DelLink(ifName)
		s := fmt.Sprintf("error setting addr for tap %s: %v", ifName, err)
		return errors.New(s)
	}

	err = SetDevUp(ifName, "")
	if err != nil {
		DelLink(ifName)
		return err
	}
	return nil
}

func DelLink(ifName string) {
	cmd := exec.Command("ip", "link", "del", ifName)
	cmd.Run()
}

func setDevUpDown(dev, ns string, isUp bool) error {
	var op string
	if isUp {
		op = "up"
	} else {
		op = "down"
	}
	c := []string{"ip", "link", "set", "dev", dev, op}
	cmd := appendNetns(c, ns)
	err := cmd.Run()
	if err != nil {
		s := fmt.Sprintf("error bringing %s device %s!", dev, op)
		return errors.New(s)
	}
	return nil
}

func AddVethPair(ifName, peerName string) error {
	cmd := exec.Command("ip", "link", "add", ifName, "type", "veth", "peer", "name", peerName)
	err := cmd.Run()
	if err != nil {
		return fmt.Errorf("creating veth pair failed: %v", err)
	}
	err = SetDevUp(ifName, "")
	if err != nil {
		return fmt.Errorf("set link up failed: %v", err)
	}
	return nil
}

func addDelNetns(name string, isAdd bool) error {
	var op string
	if isAdd {
		op = "add"
	} else {
		op = "del"
	}
	cmd := exec.Command("ip", "netns", op, name)
	_, err := cmd.CombinedOutput()
	if err != nil {
		return errors.New("add/del netns failed")
	}
	return nil
}

func AddNetns(nsName string) error {
	return addDelNetns(nsName, true)
}

func DelNetns(nsName string) error {
	return addDelNetns(nsName, false)
}

func LinkSetNetns(ifName, ns string) error {
	cmd := exec.Command("ip", "link", "set", "dev", ifName, "up", "netns", ns)
	err := cmd.Run()
	if err != nil {
		return fmt.Errorf("error setting device '%s' to netns '%s: %v", ifName, ns, err)
	}
	return nil
}

func NewCommand(s []string, ns string) *exec.Cmd {
	return appendNetns(s, ns)
}

func appendNetns(s []string, ns string) *exec.Cmd {
	var cmd *exec.Cmd
	if ns == "" {
		// use default namespace
		cmd = exec.Command(s[0], s[1:]...)
	} else {
		var args = []string{"netns", "exec", ns}
		args = append(args, s[:]...)
		cmd = exec.Command("ip", args...)
	}
	return cmd
}

func addDelBridge(brName, ns string, isAdd bool) error {
	var op string
	if isAdd {
		op = "addbr"
	} else {
		op = "delbr"
	}
	var c = []string{"brctl", op, brName}
	cmd := appendNetns(c, ns)
	err := cmd.Run()
	if err != nil {
		s := fmt.Sprintf("%s %s failed!", op, brName)
		return errors.New(s)
	}
	return nil
}

func AddBridge(brName string, ifs []string, ns string) error {
	err := addDelBridge(brName, ns, true)
	if err != nil {
		return err
	}

	for _, v := range ifs {
		c := []string{"brctl", "addif", brName, v}
		cmd := appendNetns(c, ns)
		err = cmd.Run()
		if err != nil {
			s := fmt.Sprintf("error adding %s to bridge %s: %v", v, brName, err)
			return errors.New(s)
		}
	}
	err = SetDevUp(brName, ns)
	if err != nil {
		return err
	}
	return nil
}
