package log

import (
	

	
	
)

// A PipeReader is a reader that reads from the logger. It is synchronous
// so blocking on read will affect logging performance.
type PipeReader struct {
	r      *io.PipeReader
	closer io.Closer
	core   zapcore.Core
}

// Read implements the standard Read interface
func ( *PipeReader) ( []byte) (int, error) {
	return .r.Read()
}

// Close unregisters the reader from the logger.
func ( *PipeReader) () error {
	if .core != nil {
		loggerCore.DeleteCore(.core)
	}
	return multierr.Append(.core.Sync(), .closer.Close())
}

// NewPipeReader creates a new in-memory reader that reads from all loggers
// The caller must call Close on the returned reader when done.
//
// By default, it:
//
//  1. Logs JSON. This can be changed by passing the PipeFormat option.
//  2. Logs everything that would otherwise be logged to the "primary" log
//     output. That is, everything enabled by SetLogLevel. The minimum log level
//     can be increased by passing the PipeLevel option.
func ( ...PipeReaderOption) *PipeReader {
	 := pipeReaderOptions{
		format: JSONOutput,
		level:  LevelDebug,
	}

	for ,  := range  {
		.setOption(&)
	}

	,  := io.Pipe()

	 := &PipeReader{
		r:      ,
		closer: ,
		core:   newCore(.format, zapcore.AddSync(), .level),
	}

	loggerCore.AddCore(.core)

	return 
}

type pipeReaderOptions struct {
	format LogFormat
	level  LogLevel
}

type PipeReaderOption interface {
	setOption(*pipeReaderOptions)
}

type pipeReaderOptionFunc func(*pipeReaderOptions)

func ( pipeReaderOptionFunc) ( *pipeReaderOptions) {
	()
}

// PipeFormat sets the output format of the pipe reader
func ( LogFormat) PipeReaderOption {
	return pipeReaderOptionFunc(func( *pipeReaderOptions) {
		.format = 
	})
}

// PipeLevel sets the log level of logs sent to the pipe reader.
func ( LogLevel) PipeReaderOption {
	return pipeReaderOptionFunc(func( *pipeReaderOptions) {
		.level = 
	})
}