package server

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

	"github.com/sirupsen/logrus"
)

type Server struct {
	ctx      context.Context
	cancel   context.CancelFunc
	httpSrv  *http.Server
	listener net.Listener
	handler  *http.ServeMux
	logger   *logrus.Logger
}

func (s *Server) initMux() {
	s.handler.HandleFunc("/", s.heartbeatHandler)
}

func (s *Server) heartbeatHandler(w http.ResponseWriter, r *http.Request) {
	remoteHost, _, err := net.SplitHostPort(r.RemoteAddr)
	if err != nil {
		s.logger.Warnf("Unexpected remote address %s: %q", r.RemoteAddr, err.Error())
	} else {
		s.logger.Infof("Received a heartbeat query from %s", remoteHost)
	}
	w.WriteHeader(http.StatusNoContent)
}

func (s *Server) Run(ctx context.Context) {
	s.ctx, s.cancel = context.WithCancel(ctx)
	s.initMux()
	if err := s.httpSrv.Serve(s.listener); err != nil {
		s.logger.Errorf("Failed to serve HTTP server: %s", err.Error())
	}
}

func New(addr string, logger *logrus.Logger) (*Server, error) {
	m := http.NewServeMux()
	l, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, fmt.Errorf("failed to setup listener on addr %q: %w", addr, err)
	}

	return &Server{
		ctx: context.TODO(),
		httpSrv: &http.Server{
			Handler: m,
		},
		handler:  m,
		listener: l,
		logger:   logger,
	}, nil
}
