package server

import (
	"context"
	"flag"
	"net"
	"net/http"

	"github.com/improbable-eng/grpc-web/go/grpcweb"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/reflection"
	"google.golang.org/grpc/status"
	"k8s.io/klog/v2"

	apb "source.monogon.dev/cloud/api"
	"source.monogon.dev/cloud/apigw/model"
	"source.monogon.dev/cloud/lib/component"
)

// Config is the main configuration of the apigw server. It's usually populated
// from flags via RegisterFlags, but can also be set manually (eg. in tests).
type Config struct {
	Component component.ComponentConfig
	Database  component.CockroachConfig

	PublicListenAddress string
}

// RegisterFlags registers the component configuration to be provided by flags.
// This must be called exactly once before then calling flags.Parse().
func (c *Config) RegisterFlags() {
	c.Component.RegisterFlags("apigw")
	c.Database.RegisterFlags("apigw_db")
	flag.StringVar(&c.PublicListenAddress, "apigw_public_grpc_listen_address", ":8080", "Address to listen at for public/user gRPC connections for apigw")
}

// Server runs the apigw server. It listens on two interfaces:
//  - Internal gRPC, which is authenticated using TLS and authorized by CA. This
//    is to be used for internal RPCs, eg. management/debug.
//  - Public gRPC-Web, which is currently unauthenticated.
type Server struct {
	Config Config

	// ListenGRPC will contain the address at which the internal gRPC server is
	// listening after .Start() has been called. This can differ from the configured
	// value if the configuration requests any port (via :0).
	ListenGRPC string
	// ListenPublic will contain the address at which the public API server is
	// listening after .Start() has been called. This can differ from the configured
	// value if the configuration requests any port (via :0).
	ListenPublic string
}

func (s *Server) startInternalGRPC(ctx context.Context) {
	g := grpc.NewServer(s.Config.Component.GRPCServerOptions()...)
	lis, err := net.Listen("tcp", s.Config.Component.GRPCListenAddress)
	if err != nil {
		klog.Exitf("Could not listen: %v", err)
	}
	s.ListenGRPC = lis.Addr().String()

	reflection.Register(g)

	klog.Infof("Internal gRPC listening on %s", s.ListenGRPC)
	go func() {
		err := g.Serve(lis)
		if err != ctx.Err() {
			klog.Exitf("Internal gRPC serve failed: %v", err)
		}
	}()
}

func (s *Server) startPublic(ctx context.Context) {
	g := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
	lis, err := net.Listen("tcp", s.Config.PublicListenAddress)
	if err != nil {
		klog.Exitf("Could not listen: %v", err)
	}
	s.ListenPublic = lis.Addr().String()

	reflection.Register(g)
	apb.RegisterIAMServer(g, s)

	wrapped := grpcweb.WrapServer(g)
	server := http.Server{
		Addr:    s.Config.PublicListenAddress,
		Handler: http.HandlerFunc(wrapped.ServeHTTP),
	}
	klog.Infof("Public API listening on %s", s.ListenPublic)
	go func() {
		err := server.Serve(lis)
		if err != ctx.Err() {
			klog.Exitf("Public API serve failed: %v", err)
		}
	}()
}

// Start runs the two listeners of the server. The process will fail (via
// klog.Exit) if any of the listeners/servers fail to start.
func (s *Server) Start(ctx context.Context) {
	if s.Config.Database.Migrations == nil {
		klog.Infof("Using default migrations source.")
		m, err := model.MigrationsSource()
		if err != nil {
			klog.Exitf("failed to prepare migrations source: %w", err)
		}
		s.Config.Database.Migrations = m
	}

	klog.Infof("Running migrations...")
	if err := s.Config.Database.MigrateUp(); err != nil {
		klog.Exitf("Migrations failed: %v", err)
	}
	klog.Infof("Migrations done.")
	s.startInternalGRPC(ctx)
	s.startPublic(ctx)
}

func (s *Server) WhoAmI(ctx context.Context, req *apb.WhoAmIRequest) (*apb.WhoAmIResponse, error) {
	klog.Infof("req: %+v", req)
	return nil, status.Error(codes.Unimplemented, "unimplemented")
}
