package main

import (
	"context"
	"fmt"
	"net/http"
	"sort"
	"strings"

	"code.hackerspace.pl/hscloud/go/mirko"
	"github.com/gobuffalo/packr"
	"github.com/q3k/statusz"
	"vbom.ml/util/sortorder"

	"code.hackerspace.pl/hscloud/go/svc/topo/graph"
	"code.hackerspace.pl/hscloud/go/svc/topo/state"

	pb "code.hackerspace.pl/hscloud/go/svc/topo/proto/control"
)

type Service struct {
	gr  *graph.Graph
	stm *state.StateManager
}

func NewService(gr *graph.Graph, stm *state.StateManager) *Service {
	return &Service{
		gr:  gr,
		stm: stm,
	}
}

const topologyFragment = `
  <script src="/assets/viz.js"></script>
  <script>

    var viz = new Viz({ workerURL: '/assets/full.render.js' });
	var xmlhttp = new XMLHttpRequest();
	xmlhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        var dot = this.responseText;
        viz.renderSVGElement(dot)
        .then(function(element) {
          document.getElementById("graph").appendChild(element);
        });
      }
    };
    xmlhttp.open('GET', '/debug/graphviz');
    xmlhttp.send();

  </script>
  <div id="graph" style="text-align: center;"></div>
`

const switchportsFragment = `
    <style type="text/css">
		.table td,th {
			background-color: #eee;
			padding: 0.2em 0.4em 0.2em 0.4em;
		}
		.table th {
			background-color: #c0c0c0;
		}
		.table {
			background-color: #fff;
			border-spacing: 0.2em;
			margin-left: auto;
			margin-right: auto;
		}
	</style>
	<div>
	<table class="table">
		<tr>
      		<th>Switch</th>
      		<th>Port</th>
			<th>Link State</th>
			<th>Port Mode</th>
			<th>MTU</th>
			<th>Sync Status</th>
		</tr>
		{{range .Ports }}
		{{ if .Managed }}
		<tr>
		{{ else }}
		<tr style="opacity: 0.5">
		{{ end}}
			<td style="text-align: right;">{{ .Switch }}</td>
			<td>{{ .Name }}</td>
			{{ if eq .State "DOWN" }}
			<td style="background-color: #ff3030;">{{ .State }}</td>
			{{ else }}
			<td>{{ .State }}</td>
			{{ end }}
			<td>{{ .Mode }}</td>
			<td>{{ .MTU }}</td>
			{{ if .Managed }}
			<td style="background-color: #30ff30;">OK</td>
			{{ else }}
			<td><i>Unmanaged</i></td>
			{{ end }}
		</tr>
		{{end}}
	</table>
	</div>
`

func (s *Service) Setup(m *mirko.Mirko) {
	assets := packr.NewBox("./assets")
	m.HTTPMux().Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(assets)))
	m.HTTPMux().HandleFunc("/debug/graphviz", s.httpHandleGraphviz)
	statusz.AddStatusPart("Switch Ports", switchportsFragment, s.statusHandleSwitchports)
	statusz.AddStatusPart("Topology", topologyFragment, func(ctx context.Context) interface{} {
		return nil
	})
}

func (s *Service) statusHandleSwitchports(ctx context.Context) interface{} {
	managedPorts := make(map[string]bool)
	s.gr.Mu.RLock()
	for _, sw := range s.gr.Switches {
		for _, port := range sw.Ports {
			managedPorts[sw.Name+"|"+port.Name] = true
		}
	}
	s.gr.Mu.RUnlock()

	s.stm.Mu.RLock()
	defer s.stm.Mu.RUnlock()

	res := struct {
		Ports []*struct {
			Switch  string
			Name    string
			State   string
			Mode    string
			Managed bool
			MTU     string
		}
	}{}
	for _, sw := range s.stm.Switches {
		for _, po := range sw.Ports {
			state := "INVALID"
			switch po.Proto.LinkState {
			case pb.SwitchPort_LINKSTATE_DOWN:
				state = "DOWN"
			case pb.SwitchPort_LINKSTATE_UP:
				state = "UP"
			}
			mode := "INVALID"
			switch po.Proto.PortMode {
			case pb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED:
				mode = fmt.Sprintf("UNTAGGED (%d)", po.Proto.VlanNative)
			case pb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED:
				mode = fmt.Sprintf("TAGGED (%v)", po.Proto.VlanTagged)
			case pb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC:
				mode = "GENERIC"
			case pb.SwitchPort_PORTMODE_ROUTED:
				mode = "ROUTED"
			case pb.SwitchPort_PORTMODE_MANGLED:
				mode = "MANGLED"
			}

			managed := managedPorts[sw.Name+"|"+po.Proto.Name]
			res.Ports = append(res.Ports, &struct {
				Switch  string
				Name    string
				State   string
				Mode    string
				Managed bool
				MTU     string
			}{
				Switch:  sw.Name,
				Name:    po.Proto.Name,
				State:   state,
				Mode:    mode,
				Managed: managed,
				MTU:     fmt.Sprintf("%d", po.Proto.Mtu),
			})
		}
	}

	return res
}

func (s *Service) httpHandleGraphviz(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "graph G {\n")
	fmt.Fprintf(w, "  ranksep = 2\n")
	fmt.Fprintf(w, "  splines = polyline\n")
	fmt.Fprintf(w, "  rankdir = LR\n")
	for _, machine := range s.gr.Machines {
		portNames := []string{}
		for _, port := range machine.Ports {
			name := fmt.Sprintf("<%s> %s", port.Name, port.Name)
			portNames = append(portNames, name)
		}
		ports := strings.Join(portNames, "|")
		fmt.Fprintf(w, "  %s [shape=record label=\"{ %s | { %s }}\"]\n", machine.Name, machine.Name, ports)
	}
	for _, sw := range s.gr.Switches {
		portNames := []string{}
		portsOrdered := []*graph.SwitchPort{}
		for _, port := range sw.Ports {
			portsOrdered = append(portsOrdered, port)
		}
		sort.Slice(portsOrdered, func(i, j int) bool {
			return sortorder.NaturalLess(portsOrdered[i].Name, portsOrdered[j].Name)
		})
		for _, port := range portsOrdered {
			name := fmt.Sprintf("<%s> %s", port.Name, port.Name)
			portNames = append(portNames, name)
		}
		ports := strings.Join(portNames, "|")
		fmt.Fprintf(w, "  %s [shape=record label=\"{{ %s } | %s}\"]\n", sw.Name, ports, sw.Name)
	}
	for _, machine := range s.gr.Machines {
		for _, port := range machine.Ports {
			if port.OtherEnd == nil {
				continue
			}
			fmt.Fprintf(w, "  %s:%q:e -- %s:%q:w\n", machine.Name, port.Name, port.OtherEnd.Switch.Name, port.OtherEnd.Name)
		}
	}
	fmt.Fprintf(w, "}\n")
}
