package main

import (
	"flag"
	"fmt"
	"math/rand"
	"mime"
	"net/http"
	"regexp"
	"strings"
	"sync"
	"time"

	"code.hackerspace.pl/hscloud/go/mirko"
	"github.com/golang/glog"

	"code.hackerspace.pl/hscloud/hswaw/site/calendar"
	"code.hackerspace.pl/hscloud/hswaw/site/static"
)

var (
	flagSitePublic string
)

type service struct {
	// feeds is a map from atom feed name to atom feed. This is updated by a
	// background worker.
	feeds map[string]*atomFeed
	// feedsMu locks the feeds field.
	feedsMu sync.RWMutex

	// events is a list of upcoming events, sorted so the first event is the
	// one that will happen the soonests.
	events []*calendar.UpcomingEvent
	// eventsMu locks the events field.
	eventsMu sync.RWMutex
}

func main() {
	flag.StringVar(&flagSitePublic, "site_public", "0.0.0.0:8080", "Address at which to serve public HTTP requests")
	flag.Parse()

	rand.Seed(time.Now().UnixNano())

	mi := mirko.New()
	if err := mi.Listen(); err != nil {
		glog.Exitf("Listen failed: %v", err)
	}

	s := &service{}
	go s.feedWorker(mi.Context())
	go s.eventsWorker(mi.Context())

	mux := http.NewServeMux()
	s.registerHTTP(mux)

	go func() {
		glog.Infof("Listening for public HTTP at %v", flagSitePublic)
		if err := http.ListenAndServe(flagSitePublic, mux); err != nil {
			glog.Exit(err)
		}
	}()

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

	<-mi.Done()
}

var (
	// staticRoutes define the resolution of static file paths into assets
	// built into //hswaw/site/static, whose names correspond to their origin
	// within the Bazel workspace.
	// The regexp will be matched against the normalized within the URL. If it
	// matches, its first group/submatch will be used to format the string
	// corresponding to this regexp, and that string will be then used to
	// retrieve a path embedded within //hswaw/site/static:static
	// (go_embed_data).
	//
	// To see paths available within that go_embed_data, you can do:
	//  $ bazel build //hswaw/site/static:static
	//  $ grep -A100 'Data =' bazel-bin/hswaw/site/static/static.go
	staticRoutes = map[*regexp.Regexp]string{
		regexp.MustCompile(`^static/site/(.+)$`):    "hswaw/site/static/%s",
		regexp.MustCompile(`^static/leaflet/(.+)$`): "external/com_npmjs_leaflet/package/dist/%s",
	}
)

// handleHTTPStatic uses staticRoutes to serve static files embedded within
// //hswaw/site/static.
func (s *service) handleHTTPStatic(w http.ResponseWriter, r *http.Request) {
	path := strings.TrimPrefix(r.URL.Path, "/")
	for from, to := range staticRoutes {
		match := from.FindStringSubmatch(path)
		if match == nil {
			continue
		}
		to := fmt.Sprintf(to, match[1])
		data, ok := static.Data[to]
		if !ok {
			continue
		}
		parts := strings.Split(path, ".")
		ext := fmt.Sprintf(".%s", parts[len(parts)-1])
		t := mime.TypeByExtension(ext)
		w.Header().Set("Content-Type", t)
		w.Write(data)
		return

	}
	http.NotFound(w, r)
}

func (s *service) registerHTTP(mux *http.ServeMux) {
	mux.HandleFunc("/static/", s.handleHTTPStatic)
	mux.HandleFunc("/spaceapi", s.handleSpaceAPI)
	mux.HandleFunc("/events.json", s.handleJSONEvents)
	mux.HandleFunc("/event/", s.handleEvent)
	mux.HandleFunc("/", s.handleIndex)
}
