package worker

import (
	"context"
	"net/http"
	"net/http/pprof"
	"time"

	telemetry "code.justin.tv/amzn/TwitchTelemetry"
	"code.justin.tv/creator-collab/log"
	"code.justin.tv/creator-collab/log/errors"
)

type Server struct {
	server         *http.Server
	sampleReporter *telemetry.SampleReporter
	logger         log.Logger
}

func NewServer(location string, sampleReporter *telemetry.SampleReporter, logger log.Logger) *Server {
	mux := http.NewServeMux()
	httpServer := &http.Server{
		Addr:    location,
		Handler: mux,
	}
	s := &Server{
		logger:         logger,
		server:         httpServer,
		sampleReporter: sampleReporter,
	}

	mux.HandleFunc("/health", s.handleHealthCheck)
	mux.HandleFunc("/debug/pprof/", pprof.Index)

	return s
}

func (s *Server) Start() error {
	s.logger.Debug("Starting HTTP server", log.Fields{
		"address": s.server.Addr,
	})

	err := s.server.ListenAndServe()
	if err != nil && err != http.ErrServerClosed {
		return errors.Wrap(err, "serving http server failed")
	}

	return nil
}

// Close gracefully shuts down the http server. It blocks until the server has stopped.
func (s *Server) Close(ctx context.Context) {
	s.logger.Debug("Starting to shutdown HTTP server")

	err := s.server.Shutdown(ctx)
	if err != nil {
		s.logger.Error(err)
	}

	s.logger.Debug("Completed shutting down HTTP server")
}

func (s *Server) handleHealthCheck(w http.ResponseWriter, r *http.Request) {
	startTime := time.Now()
	sampleReporter := *s.sampleReporter
	sampleReporter.OperationName = "Health"

	w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
	_, err := w.Write([]byte("OK"))
	if err != nil {
		s.logger.Error(errors.Wrap(err, "health check failed"))
		sampleReporter.ReportAvailabilitySamples(telemetry.AvailabilityCodeServerError)
		sampleReporter.ReportDurationSample(telemetry.MetricDuration, time.Since(startTime))
		return
	}

	sampleReporter.ReportAvailabilitySamples(telemetry.AvailabilityCodeSucccess)
	sampleReporter.ReportDurationSample(telemetry.MetricDuration, time.Since(startTime))
}
