package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"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/credentials"
	"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 {
	serverCert, err := tls.LoadX509KeyPair(s.opts.tlsCertificatePath, s.opts.tlsKeyPath)
	if err != nil {
		return fmt.Errorf("while loading keypair: %v", err)
	}

	certPool := x509.NewCertPool()
	ca, err := ioutil.ReadFile(s.opts.tlsCAPath)
	if err != nil {
		return fmt.Errorf("while loading ca certificate: %v", err)
	}
	if ok := certPool.AppendCertsFromPEM(ca); !ok {
		return fmt.Errorf("while appending ca certificate to pool: %v", err)
	}

	lis, err := net.Listen("tcp", s.opts.listenAddress)
	if err != nil {
		return fmt.Errorf("while listening on main port: %v", err)
	}

	creds := credentials.NewTLS(&tls.Config{
		ClientAuth:   tls.RequireAndVerifyClientCert,
		Certificates: []tls.Certificate{serverCert},
		ClientCAs:    certPool,
	})

	s.grpc.listen = lis
	options = append([]grpc.ServerOption{grpc.Creds(creds)}, options...)
	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 {}
}
