package main

import (
	"context"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"

	"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
	pkiRealm           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(grpc.UnaryInterceptor(s.unaryInterceptor)); 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)

	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 {}
}
