package main

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

	"code.hackerspace.pl/q3k/hspki"
	"github.com/golang/glog"
	"github.com/q3k/statusz"
	"golang.org/x/net/trace"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"

	pb "code.hackerspace.pl/q3k/arista-proxy/proto"
)

type serverOpts struct {
	listenAddress      string
	debugAddress       string
	tlsCAPath          string
	tlsCertificatePath string
	tlsKeyPath         string
}

type server struct {
	arista *aristaClient
	opts   *serverOpts

	grpc struct {
		listen net.Listener
		server *grpc.Server
	}
	http struct {
		listen net.Listener
		server *http.Server
	}
}

func newServer(opts *serverOpts, arista *aristaClient) (*server, error) {
	return &server{
		opts:   opts,
		arista: arista,
	}, nil
}

func (s *server) trace(ctx context.Context, f string, args ...interface{}) {
	tr, ok := trace.FromContext(ctx)
	if !ok {
		fmtd := fmt.Sprintf(f, args...)
		glog.Warningf("No trace in %v: %s", ctx, fmtd)
		return
	}
	tr.LazyPrintf(f, args...)
}

func (s *server) setupGRPC(options ...grpc.ServerOption) error {
	lis, err := net.Listen("tcp", s.opts.listenAddress)
	if err != nil {
		return fmt.Errorf("while listening on main port: %v", err)
	}

	s.grpc.listen = lis
	s.grpc.server = grpc.NewServer(options...)

	return nil
}

func (s *server) setupDebugHTTP(mux http.Handler) error {
	lis, err := net.Listen("tcp", s.opts.debugAddress)
	if err != nil {
		return fmt.Errorf("while listening on main port: %v", err)
	}

	s.http.listen = lis
	s.http.server = &http.Server{
		Addr:    s.opts.debugAddress,
		Handler: mux,
	}

	return nil
}

func (s *server) serveForever() {
	grpc.EnableTracing = true

	if err := s.setupGRPC(hspki.WithServerHSPKI()...); err != nil {
		glog.Exitf("Could not setup GRPC server: %v", err)
	}
	pb.RegisterAristaProxyServer(s.grpc.server, s)
	reflection.Register(s.grpc.server)

	go func() {
		if err := s.grpc.server.Serve(s.grpc.listen); err != nil {
			glog.Exitf("Could not start GRPC server: %v", err)
		}
	}()
	glog.Infof("Listening for GRPC on %v", s.opts.listenAddress)

	if s.opts.debugAddress == "" {
		glog.Info("Disabling debug HTTP server")
	} else {
		httpMux := http.NewServeMux()
		httpMux.HandleFunc("/debug/status", statusz.StatusHandler)
		httpMux.HandleFunc("/debug/requests", trace.Traces)
		httpMux.HandleFunc("/", statusz.StatusHandler)

		if err := s.setupDebugHTTP(httpMux); err != nil {
			glog.Exitf("Could not setup HTTP server: %v", err)
		}

		go func() {
			if err := s.http.server.Serve(s.http.listen); err != nil {
				glog.Exitf("Could not start HTTP server: %v", err)
			}
		}()
		glog.Infof("Listening for HTTP on %v", s.opts.debugAddress)
	}

	select {}
}
