package connector_webhooks

import (
	"net/http"
	"time"
)

type webhookDispatchTiming struct {
	start       time.Time
	last        time.Time
	receiptMode bool
	stage       string
	outcome     string
}

type receiptRouterStageTimer struct {
	start time.Time
	last  time.Time
}

func newWebhookDispatchTiming(receiptMode bool) *webhookDispatchTiming {
	now := time.Now()
	return &webhookDispatchTiming{
		start:       now,
		last:        now,
		receiptMode: receiptMode,
		stage:       "dispatch",
		outcome:     "started",
	}
}

func (t *webhookDispatchTiming) mark(stage, outcome string) {
	if t == nil {
		return
	}
	now := time.Now()
	recordConnectorWebhookStageDuration(stage, outcome, t.receiptMode, now.Sub(t.last).Seconds())
	t.last = now
	t.stage = stage
	t.outcome = outcome
}

func (t *webhookDispatchTiming) lastStageOutcome() (string, string) {
	if t == nil {
		return "dispatch", "unknown"
	}
	return t.stage, t.outcome
}

func (t *webhookDispatchTiming) finish(status int) {
	if t == nil {
		return
	}
	recordConnectorWebhookStageDuration("total", webhookDispatchOutcome(status), t.receiptMode, time.Since(t.start).Seconds())
}

func webhookDispatchOutcome(status int) string {
	switch {
	case status == http.StatusNoContent:
		return "ack_drop"
	case status == http.StatusAccepted:
		return "accepted"
	case status == http.StatusServiceUnavailable:
		return "unavailable"
	case status >= 500:
		return "error"
	case status >= 400:
		return "rejected"
	case status == 0:
		return "unknown"
	default:
		return "other"
	}
}

func webhookStageOutcomeOK(ok bool) string {
	if ok {
		return "ok"
	}
	return "error"
}

func newReceiptRouterStageTimer() *receiptRouterStageTimer {
	now := time.Now()
	return &receiptRouterStageTimer{start: now, last: now}
}

func (t *receiptRouterStageTimer) mark(stage, outcome string) {
	if t == nil {
		return
	}
	now := time.Now()
	recordConnectorReceiptRouterStageDuration(stage, outcome, now.Sub(t.last).Seconds())
	t.last = now
}

func (t *receiptRouterStageTimer) finish(outcome string) {
	if t == nil {
		return
	}
	recordConnectorReceiptRouterStageDuration("total", outcome, time.Since(t.start).Seconds())
}
