package csbi

import (
	"context"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"

	log "github.com/sirupsen/logrus"
	"google.golang.org/grpc"

	pb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/csbi"
)

var stopChan chan os.Signal

func init() {
	stopChan = make(chan os.Signal)
	signal.Notify(stopChan, os.Interrupt, syscall.SIGTERM)
}

// Run bootstraps the orchestrator and waits for the shutdown signal.
func Run(bindAddr string) {
	g := grpc.NewServer()
	o, err := NewOrchestrator(Docker)
	if err != nil {
		log.Fatal(err)
	}

	s := &server{
		orchestrator: o,
	}

	pb.RegisterCsbiServiceServer(g, s)
	log.Infof("starting to listen on %s", bindAddr)
	listen, err := net.Listen("tcp", bindAddr)
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		log.Info("starting to serve")
		startHttpServer()
		if err := g.Serve(listen); err != nil {
			log.Fatal(err)
		}
	}()

	log.WithFields(log.Fields{}).Info("initialisation finished")

	<-stopChan
	func() {
		log.Info("gracefully shutting down. Press Ctrl+C to force")
		signal.Reset(os.Interrupt)
		ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
		defer cancel()
		err := stopHttpServer(ctx)

		if err != nil {
			log.WithFields(log.Fields{}).Info(err)
		}

		o.Shutdown(ctx)
	}()
}
