package internal

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
)

type limitedReadCloser struct {
	*io.LimitedReader
	rc io.ReadCloser
}

// Close implements closer
func (lrc *limitedReadCloser) Close() (err error) {
	return lrc.rc.Close()
}

// WrapRequestBodyWithSeeker copies the request body into a buffer and creates
// a seekable reader. It closes the original request body. bodyLimit is used to
// limit the amount of data read from the body of the request. If 0, the reader
// is unlimited.
func WrapRequestBodyWithSeeker(r *http.Request, bodyLimit int64) (seeker io.Seeker, err error) {
	body := r.Body
	if bodyLimit > 0 {
		body = &limitedReadCloser{
			LimitedReader: &io.LimitedReader{R: r.Body, N: bodyLimit},
			rc:            r.Body,
		}
	}

	bs, err := ioutil.ReadAll(body)
	defer func() {
		closeErr := r.Body.Close()
		if err == nil {
			err = closeErr
		}
	}()
	if err != nil {
		return
	}
	br := bytes.NewReader(bs)

	r.Body = ioutil.NopCloser(br)

	seeker = br
	return
}
