package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"regexp"
	"strings"
	"time"

	"code.hackerspace.pl/hscloud/go/mirko"
	"github.com/golang/glog"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	pb "code.hackerspace.pl/hscloud/hswaw/smsgw/proto"
)

var (
	flagTwilioSID           string
	flagTwilioToken         string
	flagTwilioFriendlyPhone string

	flagWebhookListen string
	flagWebhookPublic string
)

func init() {
	flag.Set("logtostderr", "true")
}

type server struct {
	dispatcher *dispatcher
}

func ourPhoneNumber(ctx context.Context, t *twilio, friendly string) (*incomingPhoneNumber, error) {
	ipn, err := t.getIncomingPhoneNumbers(ctx)
	if err != nil {
		return nil, err
	}

	for _, pn := range ipn {
		if pn.FriendlyName == friendly {
			return &pn, nil
		}
	}

	return nil, fmt.Errorf("requested phone number %q not in list", friendly)
}

func ensureWebhook(ctx context.Context, t *twilio) {
	pn, err := ourPhoneNumber(ctx, t, flagTwilioFriendlyPhone)
	if err != nil {
		glog.Exitf("could not get our phone number: %v", err)
	}

	url := fmt.Sprintf("%ssms", flagWebhookPublic)

	// first setup.
	if pn.SMSMethod != "POST" || pn.SMSURL != url {
		glog.Infof("Updating webhook (is %s %q, want %s %q)", pn.SMSMethod, pn.SMSURL, "POST", url)
		if err := t.updateIncomingPhoneNumberSMSWebhook(ctx, pn.SID, "POST", url); err != nil {
			glog.Exitf("could not set webhook: %v")
		}

		// try again to check that it's actually set
		for {
			pn, err = ourPhoneNumber(ctx, t, flagTwilioFriendlyPhone)
			if err != nil {
				glog.Exitf("could not get our phone number: %v", err)
			}
			if pn.SMSMethod == "POST" || pn.SMSURL == url {
				break
			}
			glog.Infof("Webhook not yet ready, currently %s %q", pn.SMSMethod, pn.SMSURL)
			time.Sleep(5 * time.Second)
		}
		glog.Infof("Webhook verified")
	} else {
		glog.Infof("Webhook up to date")
	}

	// now keep checking to make sure that nobody takes over our webhook
	tick := time.NewTicker(30 * time.Second)
	for {
		select {
		case <-ctx.Done():
			return
		case <-tick.C:
			pn, err = ourPhoneNumber(ctx, t, flagTwilioFriendlyPhone)
			if err != nil {
				glog.Exitf("could not get our phone number: %v", err)
			}
			if pn.SMSMethod != "POST" || pn.SMSURL != url {
				glog.Exitf("Webhook got deconfigured, not %s %q", pn.SMSMethod, pn.SMSURL)
			}
		}
	}
}

func (s *server) webhookHandler(w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		glog.Errorf("webhook body parse error: %v", err)
		return
	}

	accountSID := r.PostForm.Get("AccountSid")
	if accountSID != flagTwilioSID {
		glog.Errorf("webhook got wrong account sid, got %q, wanted %q", accountSID, flagTwilioSID)
		return
	}

	body := r.PostForm.Get("Body")
	if body == "" {
		return
	}

	from := r.PostForm.Get("From")

	glog.Infof("Got SMS from %q, body %q", from, body)

	s.dispatcher.publish(&sms{
		from:      from,
		body:      body,
		timestamp: time.Now(),
	})

	w.WriteHeader(200)
}

func main() {
	flag.StringVar(&flagTwilioSID, "twilio_sid", "", "Twilio account SID")
	flag.StringVar(&flagTwilioToken, "twilio_token", "", "Twilio auth token")
	flag.StringVar(&flagTwilioFriendlyPhone, "twilio_friendly_phone", "", "Twilio friendly phone number")

	flag.StringVar(&flagWebhookListen, "webhook_listen", "127.0.0.1:5000", "Listen address for webhook handler")
	flag.StringVar(&flagWebhookPublic, "webhook_public", "", "Public address for webhook handler (wg. http://proxy.q3k.org/smsgw/)")
	flag.Parse()

	if flagTwilioSID == "" || flagTwilioToken == "" {
		glog.Exitf("twilio_sid and twilio_token must be set")
	}

	if flagTwilioFriendlyPhone == "" {
		glog.Exitf("twilio_friendly_phone must be set")
	}

	if flagWebhookPublic == "" {
		glog.Exitf("webhook_public must be set")
	}

	if !strings.HasSuffix(flagWebhookPublic, "/") {
		flagWebhookPublic += "/"
	}

	s := &server{
		dispatcher: newDispatcher(),
	}

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

	webhookMux := http.NewServeMux()
	webhookMux.HandleFunc("/sms", s.webhookHandler)
	webhookSrv := http.Server{
		Addr:    flagWebhookListen,
		Handler: webhookMux,
	}
	go func() {
		if err := webhookSrv.ListenAndServe(); err != nil {
			glog.Exitf("webhook ListenAndServe: %v", err)
		}
	}()

	t := &twilio{
		accountSID:   flagTwilioSID,
		accountToken: flagTwilioToken,
	}
	go ensureWebhook(m.Context(), t)
	go s.dispatcher.run(m.Context())

	pb.RegisterSMSGatewayServer(m.GRPC(), s)

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

	<-m.Done()
}

func (s *server) Messages(req *pb.MessagesRequest, stream pb.SMSGateway_MessagesServer) error {
	re := regexp.MustCompile(".*")
	if req.FilterBody != "" {
		var err error
		re, err = regexp.Compile(req.FilterBody)
		if err != nil {
			return status.Errorf(codes.InvalidArgument, "filter regexp error: %v", err)
		}
	}

	data := make(chan *sms)
	cancel := make(chan struct{})
	defer func() {
		close(cancel)
		close(data)
	}()

	s.dispatcher.subscribe(&subscriber{
		re:     re,
		data:   data,
		cancel: cancel,
	})

	for d := range data {
		stream.Send(&pb.MessagesResponse{
			Sender:    d.from,
			Body:      d.body,
			Timestamp: d.timestamp.UnixNano(),
		})
	}

	return nil
}
