// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package output

import (
	"fmt"

	"go.chromium.org/luci/logdog/api/logpb"
	"go.chromium.org/luci/logdog/client/butler/bootstrap"
)

// Output is a sink endpoint for groups of messages.
//
// An Output's methods must be goroutine-safe.
//
// Note that there is no guarantee that any of the bundles passed through an
// Output are ordered.
type Output interface {
	// SendBundle sends a constructed ButlerLogBundle through the Output.
	//
	// If an error is returned, it indicates a failure to send the bundle.
	// If there is a data error or a message type is not supported by the
	// Output, it should log the error and return nil.
	SendBundle(*logpb.ButlerLogBundle) error

	// MaxSendBundles is the number of concurrent calls to SendBundle allowed.
	//
	// If <= 0, only one SendBundle will be called at a time.
	MaxSendBundles() int

	// URLConstructionEnv should return a bootstrap.Environment containing
	// any fields necessary for clients to construct a URL pointing to where this
	// Output is sending its data.
	//
	// Returning an empty Environment means that clients will not be able to
	// construct URLs to this data (which may be accurate, depending on the
	// Output implementation).
	//
	// StreamServerURI is ignored and should not be specified.
	//
	// NOTE: This is an awful encapsulation violation. We should change the butler
	// protocol so that opening a new stream has the butler immediately reply with
	// the externally-visible URL to the stream and stop exporting these envvars
	// entirely.
	URLConstructionEnv() bootstrap.Environment

	// MaxSize returns the maximum number of bytes that this Output can process
	// with a single send. A return value <=0 indicates that there is no fixed
	// maximum size for this Output.
	//
	// Since it is impossible for callers to know the actual size of the message
	// that is being submitted, and since message batching may cluster across
	// size boundaries, this should be a conservative estimate.
	MaxSize() int

	// Collect current Output stats.
	Stats() Stats

	// Close closes the Output, blocking until any buffered actions are flushed.
	Close()
}

// Stats is an interface to query Output statistics.
//
// An Output's ability to keep statistics varies with its implementation
// details. Currently, Stats are for debugging/information purposes only.
type Stats interface {
	fmt.Stringer

	// SentBytes returns the number of bytes
	SentBytes() int64
	// SentMessages returns the number of successfully transmitted messages.
	SentMessages() int64
	// DiscardedMessages returns the number of discarded messages.
	DiscardedMessages() int64
	// Errors returns the number of errors encountered during operation.
	Errors() int64
}

// StatsBase is a simple implementation of the Stats interface.
type StatsBase struct {
	F struct {
		SentBytes         int64 // The number of bytes sent.
		SentMessages      int64 // The number of messages sent.
		DiscardedMessages int64 // The number of messages that have been discarded.
		Errors            int64 // The number of errors encountered.
	}
}

var _ Stats = (*StatsBase)(nil)

func (s *StatsBase) String() string {
	return fmt.Sprintf("%+v", s.F)
}

// SentBytes implements Stats.
func (s *StatsBase) SentBytes() int64 {
	return s.F.SentBytes
}

// SentMessages implements Stats.
func (s *StatsBase) SentMessages() int64 {
	return s.F.SentMessages
}

// DiscardedMessages implements Stats.
func (s *StatsBase) DiscardedMessages() int64 {
	return s.F.DiscardedMessages
}

// Errors implements Stats.
func (s *StatsBase) Errors() int64 {
	return s.F.Errors
}

// Merge merges the values from one Stats block into another.
func (s *StatsBase) Merge(o Stats) {
	s.F.SentBytes += o.SentBytes()
	s.F.SentMessages += o.SentMessages()
	s.F.DiscardedMessages += o.DiscardedMessages()
	s.F.Errors += o.Errors()
}
