// Package ioutil implements some I/O utility functions.
package ioutil

import (
	"bufio"
	"context"
	"errors"
	"io"

	"github.com/jbenet/go-context/io"
)

type readPeeker interface {
	io.Reader
	Peek(int) ([]byte, error)
}

var (
	ErrEmptyReader = errors.New("reader is empty")
)

// NonEmptyReader takes a reader and returns it if it is not empty, or
// `ErrEmptyReader` if it is empty. If there is an error when reading the first
// byte of the given reader, it will be propagated.
func NonEmptyReader(r io.Reader) (io.Reader, error) {
	pr, ok := r.(readPeeker)
	if !ok {
		pr = bufio.NewReader(r)
	}

	_, err := pr.Peek(1)
	if err == io.EOF {
		return nil, ErrEmptyReader
	}

	if err != nil {
		return nil, err
	}

	return pr, nil
}

type readCloser struct {
	io.Reader
	closer io.Closer
}

func (r *readCloser) Close() error {
	return r.closer.Close()
}

// NewReadCloser creates an `io.ReadCloser` with the given `io.Reader` and
// `io.Closer`.
func NewReadCloser(r io.Reader, c io.Closer) io.ReadCloser {
	return &readCloser{Reader: r, closer: c}
}

type writeCloser struct {
	io.Writer
	closer io.Closer
}

func (r *writeCloser) Close() error {
	return r.closer.Close()
}

// NewWriteCloser creates an `io.WriteCloser` with the given `io.Writer` and
// `io.Closer`.
func NewWriteCloser(w io.Writer, c io.Closer) io.WriteCloser {
	return &writeCloser{Writer: w, closer: c}
}

type writeNopCloser struct {
	io.Writer
}

func (writeNopCloser) Close() error { return nil }

// WriteNopCloser returns a WriteCloser with a no-op Close method wrapping
// the provided Writer w.
func WriteNopCloser(w io.Writer) io.WriteCloser {
	return writeNopCloser{w}
}

// CheckClose calls Close on the given io.Closer. If the given *error points to
// nil, it will be assigned the error returned by Close. Otherwise, any error
// returned by Close will be ignored. CheckClose is usually called with defer.
func CheckClose(c io.Closer, err *error) {
	if cerr := c.Close(); cerr != nil && *err == nil {
		*err = cerr
	}
}

// NewContextWriter wraps a writer to make it respect given Context.
// If there is a blocking write, the returned Writer will return whenever the
// context is cancelled (the return values are n=0 and err=ctx.Err()).
func NewContextWriter(ctx context.Context, w io.Writer) io.Writer {
	return ctxio.NewWriter(ctx, w)
}

// NewContextReader wraps a reader to make it respect given Context.
// If there is a blocking read, the returned Reader will return whenever the
// context is cancelled (the return values are n=0 and err=ctx.Err()).
func NewContextReader(ctx context.Context, r io.Reader) io.Reader {
	return ctxio.NewReader(ctx, r)
}

// NewContextWriteCloser as NewContextWriter but with io.Closer interface.
func NewContextWriteCloser(ctx context.Context, w io.WriteCloser) io.WriteCloser {
	ctxw := ctxio.NewWriter(ctx, w)
	return NewWriteCloser(ctxw, w)
}

// NewContextReadCloser as NewContextReader but with io.Closer interface.
func NewContextReadCloser(ctx context.Context, r io.ReadCloser) io.ReadCloser {
	ctxr := ctxio.NewReader(ctx, r)
	return NewReadCloser(ctxr, r)
}

type readerOnError struct {
	io.Reader
	notify func(error)
}

// NewReaderOnError returns a io.Reader that call the notify function when an
// unexpected (!io.EOF) error happens, after call Read function.
func NewReaderOnError(r io.Reader, notify func(error)) io.Reader {
	return &readerOnError{r, notify}
}

// NewReadCloserOnError returns a io.ReadCloser that call the notify function
// when an unexpected (!io.EOF) error happens, after call Read function.
func NewReadCloserOnError(r io.ReadCloser, notify func(error)) io.ReadCloser {
	return NewReadCloser(NewReaderOnError(r, notify), r)
}

func (r *readerOnError) Read(buf []byte) (n int, err error) {
	n, err = r.Reader.Read(buf)
	if err != nil && err != io.EOF {
		r.notify(err)
	}

	return
}

type writerOnError struct {
	io.Writer
	notify func(error)
}

// NewWriterOnError returns a io.Writer that call the notify function when an
// unexpected (!io.EOF) error happens, after call Write function.
func NewWriterOnError(w io.Writer, notify func(error)) io.Writer {
	return &writerOnError{w, notify}
}

// NewWriteCloserOnError returns a io.WriteCloser that call the notify function
//when an unexpected (!io.EOF) error happens, after call Write function.
func NewWriteCloserOnError(w io.WriteCloser, notify func(error)) io.WriteCloser {
	return NewWriteCloser(NewWriterOnError(w, notify), w)
}

func (r *writerOnError) Write(p []byte) (n int, err error) {
	n, err = r.Writer.Write(p)
	if err != nil && err != io.EOF {
		r.notify(err)
	}

	return
}
