package main

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

	"code.hackerspace.pl/hscloud/go/mirko"
	ipb "code.hackerspace.pl/hscloud/go/proto/infra"
	"code.hackerspace.pl/hscloud/go/statusz"
	"code.hackerspace.pl/hscloud/go/svc/topo/graph"
	"code.hackerspace.pl/hscloud/go/svc/topo/state"
	"github.com/gobuffalo/packr"
	"vbom.ml/util/sortorder"
)

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 ipb.SwitchPort_LINKSTATE_DOWN:
				state = "DOWN"
			case ipb.SwitchPort_LINKSTATE_UP:
				state = "UP"
			}
			mode := "INVALID"
			switch po.Proto.PortMode {
			case ipb.SwitchPort_PORTMODE_SWITCHPORT_UNTAGGED:
				mode = fmt.Sprintf("UNTAGGED (%d)", po.Proto.VlanNative)
			case ipb.SwitchPort_PORTMODE_SWITCHPORT_TAGGED:
				mode = fmt.Sprintf("TAGGED (%v)", po.Proto.VlanTagged)
			case ipb.SwitchPort_PORTMODE_SWITCHPORT_GENERIC:
				mode = "GENERIC"
			case ipb.SwitchPort_PORTMODE_ROUTED:
				mode = "ROUTED"
			case ipb.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")
}
