package graph

import (
	"context"
	"fmt"

	"github.com/digitalocean/go-netbox/netbox/client"
	"github.com/digitalocean/go-netbox/netbox/client/dcim"
	"github.com/digitalocean/go-netbox/netbox/models"
	"github.com/golang/glog"

	confpb "code.hackerspace.pl/q3k/topo/proto/config"
)

type MachinePort struct {
	Machine  *Machine
	OtherEnd *SwitchPort
	Name     string
}

type SwitchPort struct {
	Switch   *Switch
	OtherEnd *MachinePort
	Name     string
}

type Machine struct {
	Name     string
	Complete bool

	Ports map[string]*MachinePort
}

type Switch struct {
	Name     string
	Complete bool

	Ports map[string]*SwitchPort
}

type Graph struct {
	Switches map[string]*Switch
	Machines map[string]*Machine
}

func New() *Graph {
	return &Graph{
		Switches: make(map[string]*Switch),
		Machines: make(map[string]*Machine),
	}
}

func (g *Graph) RemoveMachine(name string) {
	glog.Infof("Removed machine %q", name)
}

func (g *Graph) RemoveSwitch(name string) {
	glog.Infof("Removed switch %q", name)
}

func (g *Graph) LoadConfig(conf *confpb.Config) error {
	loadedMachines := make(map[string]bool)
	loadedSwitches := make(map[string]bool)

	// Add new machines and switches.
	for _, machinepb := range conf.Machine {
		if machinepb.Name == "" {
			return fmt.Errorf("empty machine name")
		}
		if loadedMachines[machinepb.Name] {
			return fmt.Errorf("duplicate machine name: %v", machinepb.Name)
		}
		machine, ok := g.Machines[machinepb.Name]
		if !ok {
			machine = &Machine{
				Name:  machinepb.Name,
				Ports: make(map[string]*MachinePort),
			}
			for _, portpb := range machinepb.ManagedPort {
				machine.Ports[portpb.Name] = &MachinePort{
					Name:    portpb.Name,
					Machine: machine,
				}
			}
			g.Machines[machinepb.Name] = machine
			glog.Infof("Added machine %q with %d managed ports", machine.Name, len(machine.Ports))
		}
		machine.Complete = false
		loadedMachines[machinepb.Name] = true
	}
	for _, switchpb := range conf.Switch {
		if switchpb.Name == "" {
			return fmt.Errorf("empty switch name")
		}
		if loadedSwitches[switchpb.Name] {
			return fmt.Errorf("duplicate switch name: %v", switchpb.Name)
		}
		if loadedMachines[switchpb.Name] {
			return fmt.Errorf("switch name collides with machine name: %v", switchpb.Name)
		}
		sw, ok := g.Switches[switchpb.Name]
		if !ok {
			sw = &Switch{
				Name:  switchpb.Name,
				Ports: make(map[string]*SwitchPort),
			}
			for _, portpb := range switchpb.ManagedPort {
				sw.Ports[portpb.Name] = &SwitchPort{
					Name:   portpb.Name,
					Switch: sw,
				}
			}
			g.Switches[switchpb.Name] = sw
			glog.Infof("Added switch %q with %d managed ports", sw.Name, len(sw.Ports))
		}
		sw.Complete = false
		loadedSwitches[switchpb.Name] = true
	}

	// Remove old machines and switches.
	removeMachines := make(map[string]bool)
	removeSwitches := make(map[string]bool)
	for name, _ := range g.Switches {
		if !loadedSwitches[name] {
			removeSwitches[name] = true
		}
	}
	for name, _ := range g.Machines {
		if !loadedMachines[name] {
			removeMachines[name] = true
		}
	}
	for name, _ := range removeMachines {
		g.RemoveMachine(name)
	}
	for name, _ := range removeSwitches {
		g.RemoveSwitch(name)
	}
	return nil

}

func (g *Graph) FeedFromNetbox(ctx context.Context, nb *client.NetBox) error {
	// Clear all connections first, because it's easier that way.
	for _, machine := range g.Machines {
		for _, port := range machine.Ports {
			port.OtherEnd = nil
		}
	}
	for _, sw := range g.Switches {
		for _, port := range sw.Ports {
			port.OtherEnd = nil
		}
	}

	// Load new connections.
	// Iterating over just machines should be fine if all connections are
	// guaranteed to be between machines and switches (which is the model for
	// now).
	for _, machine := range g.Machines {
		req := &dcim.DcimInterfaceConnectionsListParams{
			Device:  &machine.Name,
			Context: ctx,
		}
		res, err := nb.Dcim.DcimInterfaceConnectionsList(req, nil)
		if err != nil {
			return fmt.Errorf("while querying information about %q: %v", machine.Name, err)
		}
		for _, connection := range res.Payload.Results {
			ia := connection.InterfaceA
			ib := connection.InterfaceB
			if ia == nil || ib == nil {
				continue
			}

			// Find which way this thing actually connects.
			var thisSide, otherSide *models.PeerInterface
			if ia.Device.Name == machine.Name {
				thisSide = ia
				otherSide = ib
			} else if ib.Device.Name == machine.Name {
				thisSide = ib
				otherSide = ia
			} else {
				glog.Warning("Netbox connectivity for %q reported a link without it involced..?", machine.Name)
				continue
			}

			thisPort, ok := machine.Ports[*thisSide.Name]
			if !ok {
				continue
			}
			sw, ok := g.Switches[otherSide.Device.Name]
			if !ok {
				glog.Warningf("Machine %q port %q is managed but connected to unknown device %q", machine.Name, thisPort.Name, otherSide.Device.Name)
				continue
			}
			otherPort, ok := sw.Ports[*otherSide.Name]
			if !ok {
				glog.Warningf("Machine %q port %q is managed but connected to unmanaged port %q on %q", machine.Name, thisPort.Name, otherSide.Name, sw.Name)
				continue
			}

			// Connect the two together!
			thisPort.OtherEnd = otherPort
			otherPort.OtherEnd = thisPort
			glog.Infof("Connected: %s/%s <-> %s/%s", machine.Name, thisPort.Name, sw.Name, otherPort.Name)
		}
	}
	return nil
}
