package main

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"sync"
	"time"

	"code.hackerspace.pl/hscloud/go/mirko"
	"github.com/golang/glog"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"

	pb "code.hackerspace.pl/hscloud/personal/q3k/shipstuck/proto"
)

type vessel struct {
	// No idea what these fields are, but they seem to be related to
	// latitude/longitude. Use these to detect the stuckness of the ship.
	GT int64 `json:"gt"`
	DW int64 `json:"dw"`
}

// get retrieves the current status of the ship - returns true if stack, false
// otherwise.
func get(ctx context.Context) (bool, error) {
	// Sorry vesselfinder, if you made it easy to set up an account I would
	// gladly pay for the API instead of doing this. Limiting requests to once
	// every 15 minutes though, that seems fair enough.
	req, err := http.NewRequestWithContext(ctx, "GET", "https://www.vesselfinder.com/api/pub/click/353136000", nil)
	if err != nil {
		return false, fmt.Errorf("NewRequestWithContext: %w", err)
	}
	req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return false, fmt.Errorf("Do: %w", err)
	}

	defer res.Body.Close()

	v := &vessel{}
	err = json.NewDecoder(res.Body).Decode(v)
	if err != nil {
		return false, fmt.Errorf("Decode: %w", err)
	}

	if v.GT == 219079 && v.DW == 199489 {
		return true, nil
	} else {
		glog.Infof("Freed! %+v", v)
		return false, nil
	}
}

type shipState string

const (
	shipStateUnknown shipState = "UNKNOWN"
	shipStateStuck   shipState = "STUCK"
	shipStateFreed   shipState = "FREED"
)

type service struct {
	lastStateMu   sync.RWMutex
	lastState     shipState
	lastStateTime time.Time
}

func (s *service) worker(ctx context.Context) {
	update := func() {
		state := shipStateUnknown
		// shitty back off, good enough.
		retries := 10
		for {
			stuck, err := get(ctx)
			if err != nil {
				glog.Warningf("get: %v", err)
				if retries > 0 {
					time.Sleep(60 * time.Second)
					retries -= 1
				} else {
					glog.Errorf("giving up on get")
					break
				}
			} else {
				if stuck {
					state = shipStateStuck
				} else {
					state = shipStateFreed
				}
				break
			}
		}

		glog.Infof("New state: %v", state)
		s.lastStateMu.Lock()
		s.lastState = state
		s.lastStateTime = time.Now()
		s.lastStateMu.Unlock()
	}

	update()
	ticker := time.NewTicker(15 * 60 * time.Second)
	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			update()
		}
	}
}

func timeMust(t time.Time, err error) time.Time {
	if err != nil {
		panic(err)
	}
	return t
}

var (
	timeStuck = timeMust(time.Parse(
		"At 15:04 Eastern European Time (MST) on 2 January 2006",
		"At 07:40 Eastern European Time (UTC) on 23 March 2021",
	))
)

func (s *service) Status(ctx context.Context, req *pb.StatusRequest) (*pb.StatusResponse, error) {
	s.lastStateMu.RLock()
	state := s.lastState
	lastChecked := s.lastStateTime
	s.lastStateMu.RUnlock()

	res := &pb.StatusResponse{
		LastChecked: lastChecked.UnixNano(),
	}
	switch state {
	case shipStateUnknown:
		res.Current = pb.StatusResponse_STUCKNESS_UNKNOWN
	case shipStateStuck:
		res.Current = pb.StatusResponse_STUCKNESS_STUCK
		res.Elapsed = time.Since(timeStuck).Nanoseconds()
	case shipStateFreed:
		res.Current = pb.StatusResponse_STUCKNESS_FREE
	}

	return res, nil
}

var (
	flagPublicAddress string
)

func main() {
	flag.StringVar(&flagPublicAddress, "public_address", "127.0.0.1:8080", "Public HTTP/JSON listen address")
	flag.Parse()
	m := mirko.New()
	if err := m.Listen(); err != nil {
		glog.Exitf("Listen(): %v", err)
	}

	s := &service{}
	pb.RegisterShipStuckServer(m.GRPC(), s)

	publicMux := runtime.NewServeMux()
	publicSrv := http.Server{
		Addr:    flagPublicAddress,
		Handler: publicMux,
	}
	go func() {
		glog.Infof("REST listening on %s", flagPublicAddress)
		if err := publicSrv.ListenAndServe(); err != nil {
			glog.Exitf("public ListenAndServe: %v", err)
		}
	}()
	if err := pb.RegisterShipStuckHandlerServer(m.Context(), publicMux, s); err != nil {
		glog.Exitf("RegisterShipStuckHandlerSerever: %v", err)
	}

	go s.worker(m.Context())

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

	<-m.Done()
}
