// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build linux || darwin
// +build linux darwin

package schedule

import (
	"bytes"
	"fmt"
	"strings"
	"time"

	clog "golang.org/x/build/internal/coordinator/log"
	"golang.org/x/build/internal/coordinator/pool"
	"golang.org/x/build/types"
)

type Spanner interface {
	SpanRecord(*Span, error) *types.SpanRecord
}

// Span is an event covering a region of time.
// A Span ultimately ends in an error or success, and will eventually
// be visualized and logged.
type Span struct {
	event   string // event name like "get_foo" or "write_bar"
	optText string // optional details for event
	start   time.Time
	end     time.Time
	el      pool.EventTimeLogger // where we log to at the end; TODO: this will change
}

// Event is the span's event.
func (s *Span) Event() string {
	return s.event
}

// OptText is the optional text for a span.
func (s *Span) OptText() string {
	return s.optText
}

// Start is the start time for the span..
func (s *Span) Start() time.Time {
	return s.start
}

// End is the end time for an span.
func (s *Span) End() time.Time {
	return s.end
}

// CreateSpan creates a span with the appropriate metadata. It also starts the span.
func CreateSpan(el pool.EventTimeLogger, event string, optText ...string) *Span {
	start := time.Now()
	el.LogEventTime(event, optText...)
	return &Span{
		el:      el,
		event:   event,
		start:   start,
		optText: strings.Join(optText, " "),
	}
}

// Done ends a span.
// It is legal to call Done multiple times. Only the first call
// logs.
// Done always returns its input argument.
func (s *Span) Done(err error) error {
	if !s.end.IsZero() {
		return err
	}
	t1 := time.Now()
	s.end = t1
	td := t1.Sub(s.start)
	var text bytes.Buffer
	fmt.Fprintf(&text, "after %s", friendlyDuration(td))
	if err != nil {
		fmt.Fprintf(&text, "; err=%v", err)
	}
	if s.optText != "" {
		fmt.Fprintf(&text, "; %v", s.optText)
	}
	if st, ok := s.el.(Spanner); ok {
		clog.CoordinatorProcess().PutSpanRecord(st.SpanRecord(s, err))
	}
	s.el.LogEventTime("finish_"+s.event, text.String())
	return err
}

// TODO: This is a copy of the function in cmd/coordinator/status.go. This should be removed once status
// is moved into it's own package.
func friendlyDuration(d time.Duration) string {
	if d > 10*time.Second {
		d2 := ((d + 50*time.Millisecond) / (100 * time.Millisecond)) * (100 * time.Millisecond)
		return d2.String()
	}
	if d > time.Second {
		d2 := ((d + 5*time.Millisecond) / (10 * time.Millisecond)) * (10 * time.Millisecond)
		return d2.String()
	}
	d2 := ((d + 50*time.Microsecond) / (100 * time.Microsecond)) * (100 * time.Microsecond)
	return d2.String()
}
