package main

import (
	"context"
	"flag"
	"fmt"
	"html/template"
	"net"
	"net/http"
	"math/rand"
	"strings"
	"time"

	"github.com/golang/glog"

	mirko "code.hackerspace.pl/hscloud/go/mirko"
	"code.hackerspace.pl/hscloud/hswaw/laserproxy/tpl"
)

var (
	flagLaserAddress = "10.11.0.10"
	flagLaserNetworkAddress = "10.11.0.1"
	flagClientNetworkAddress = "10.8.1.2"
	flagWebAddress = "127.0.0.1:8080"
	flagOwnershipDuration = "1h"

	tplIndex = template.Must(template.New("index.html").Parse(tpl.MustAssetString("index.html")))
)

type service struct {
	lockCtrl chan *lockCtrl
}

func main() {
	flag.StringVar(&flagLaserAddress, "laser_address", flagLaserAddress, "Address of Ruida controller on laser network")
	flag.StringVar(&flagLaserNetworkAddress, "laser_network", flagLaserNetworkAddress, "Address of proxy on laser network")
	flag.StringVar(&flagClientNetworkAddress, "client_network", flagClientNetworkAddress, "Address of proxy on client network")
	flag.StringVar(&flagWebAddress, "web_address", flagWebAddress, "Address and port to listen on for public web connections")
	flag.StringVar(&flagOwnershipDuration, "timeout_duration", flagOwnershipDuration, "Time after which lasercutter lock will expire when not in use")

	flag.Parse()
	m := mirko.New()
	if err := m.Listen(); err != nil {
		glog.Exitf("Could not listen: %v", err)
	}

	lisLaser, err := net.ListenPacket("udp", fmt.Sprintf("%s:40200", flagLaserNetworkAddress))
	if err != nil {
		glog.Fatalf("could not listen on laser network: %v", err)
	}
	defer lisLaser.Close()

	lisClient, err := net.ListenPacket("udp", fmt.Sprintf("%s:50200", flagClientNetworkAddress))
	if err != nil {
		glog.Fatalf("could not listen on client network: %v", err)
	}
	defer lisClient.Close()

	laserIP := net.ParseIP(flagLaserAddress)
	if laserIP == nil {
		glog.Fatalf("could not parse laser IP address %q", flagLaserAddress)
	}
	laserAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:50200", laserIP.String()))
	if err != nil {
		glog.Fatalf("could not make laser UDP address: %v", err)
	}

	ownershipDuration, err := time.ParseDuration(flagOwnershipDuration)
	if err != nil {
		glog.Fatalf("could not parse timeout duration: %v", err)
	}

	ctx := m.Context()
	s := &service{
		lockCtrl: make(chan *lockCtrl),
	}
	updates := make(chan *lockUpdate)
	go s.runProxy(ctx, updates, laserAddr, lisLaser, lisClient)
	go s.runLocker(ctx, s.lockCtrl, ownershipDuration)
	s.lockCtrl <- &lockCtrl{
		subscribe: &lockCtrlSubscribe{
			subscriber: updates,
		},
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/", s.handlerIndex)
	mux.HandleFunc("/take", s.handlerTake)
	mux.HandleFunc("/release", s.handlerRelease)
	mux.HandleFunc("/force", s.handlerForce)
	httpSrv := &http.Server{Addr: flagWebAddress, Handler: mux}

	glog.Infof("Listening for web connections on %q...", flagWebAddress)
	go func() {
		if err := httpSrv.ListenAndServe(); err != nil {
			glog.Error(err)
		}
	}()

	if err := m.Serve(); err != nil {
		glog.Exitf("Could not run: %v", err)
	}

	glog.Info("Running.")
	<-m.Done()
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	httpSrv.Shutdown(ctx)
}

var (
	sampleNames = []string{
		"elia", "radex", "qdot", "hans acker", "lars aser", "makłowicz",
	}
)

func remoteAddr(r *http.Request) string {
	if fwd := r.Header.Get("X-Forwarded-For"); fwd != "" {
		return strings.Split(fwd, ":")[0]
	}
	return strings.Split(r.RemoteAddr, ":")[0]
}

func (s *service) handlerIndex(w http.ResponseWriter, r *http.Request) {
	res := make(chan *lockResCurrent)
	s.lockCtrl <- &lockCtrl{
		getCurrent: &lockCtrlGetCurrent{
			res: res,
		},
	}
	cur := <-res

	err := tplIndex.Execute(w, struct {
		You bool
		CurrentAddress string
		CurrentName string
		CurrentDeadline string
		SampleName string
	}{
		You: cur.addr == remoteAddr(r),
		CurrentAddress: cur.addr,
		CurrentName: cur.note,
		CurrentDeadline: fmt.Sprintf("%d minute(s)", int(cur.deadline.Sub(time.Now()).Minutes())),
		SampleName: sampleNames[rand.Intn(len(sampleNames))],
	})
	if err != nil {
		glog.Errorf("rendering template: %v", err)
	}
}

func (s *service) handlerTake(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		return
	}
	r.ParseForm()
	who := r.Form.Get("who")
	prev := r.Form.Get("prev")
	if who == "" {
		fmt.Fprintf(w, "excuse me, who are you? please specify a name")
		return
	}

	res := make(chan bool)
	take := &lockCtrlTake{
		note: who,
		addr: remoteAddr(r),
		prev: prev,
		res: res,
	}
	s.lockCtrl <- &lockCtrl{
		take: take,
	}
	won := <-res

	if won {
		http.Redirect(w, r, "/", 302)
	} else {
		fmt.Fprintf(w, "lock not taken")
	}
}

func (s *service) handlerRelease(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		return
	}
	res := make(chan struct{})
	s.lockCtrl <- &lockCtrl{
		release: &lockCtrlRelease{
			addr: remoteAddr(r),
			res: res,
		},
	}
	<-res

	http.Redirect(w, r, "/", 302)
}

func (s *service) handlerForce(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		return
	}
	res := make(chan struct{})
	s.lockCtrl <- &lockCtrl{
		release: &lockCtrlRelease{
			force: true,
			res: res,
		},
	}
	<-res

	http.Redirect(w, r, "/", 302)
}
