package httprange

import (
	
	
	
)

var _ interface {
	io.ReaderAt
	io.Reader
	io.Seeker
	io.Closer
} = (*BytesResourceReader)(nil)

// BytesResource represents a resource with a known length that supports byte
// range requests.
type BytesResource struct {
	// Length is the complete length of the resource in bytes.
	Length int64

	// Ranger is the Ranger instance for performing range requests.
	Ranger Ranger
}

// Reader returns a [BytesResourceReader] for reading the resource.
//
// The provided context controls the lifetime of the reader; canceling it will
// abort any in-flight range requests.
//
// The returned reader must be closed after use by calling its Close method.
func ( *BytesResource) ( context.Context) *BytesResourceReader {
	,  := context.WithCancelCause()
	 := &BytesReader{
		Context: ,
		Ranger:  .Ranger,
	}
	return &BytesResourceReader{
		Reader: ,
		Cancel: ,
		Length: .Length,
	}
}

// BytesResourceReader provides sequential and random access to a [BytesResource].
// It implements [io.ReaderAt], [io.Reader], [io.Seeker], and [io.Closer].
type BytesResourceReader struct {
	// Reader is the underlying resource reader.
	Reader io.ReaderAt

	// Cancel is a function that cancels reads.
	Cancel context.CancelCauseFunc

	// Length is the complete length of the resource in bytes.
	Length int64

	// Offset is the current offset for reading and seeking.
	Offset int64 // mutable
}

// ReadAt reads len(p) bytes from offset off into p.
func ( *BytesResourceReader) ( []byte,  int64) (int, error) {
	if  < 0 {
		return 0, errors.New("httprange: negative read offset")
	}
	if  >= .Length {
		return 0, io.EOF
	}
	,  := .slice(, )
	,  := .Reader.ReadAt(, )
	switch {
	case  &&  == nil:
		 = io.EOF
	case ! &&  == io.EOF:
		 = io.ErrUnexpectedEOF
	}
	return , 
}

func ( *BytesResourceReader) ( []byte,  int64) ([]byte, bool) {
	 := .Length - 
	if int64(len()) >  {
		return [:], true
	}
	return , int64(len()) == 
}

// Read reads up to len(p) bytes into p.
func ( *BytesResourceReader) ( []byte) (int, error) {
	,  := .ReadAt(, .Offset)
	.Offset += int64()
	return , 
}

// Seek sets the offset for the next read.
func ( *BytesResourceReader) ( int64,  int) (int64, error) {
	switch  {
	case io.SeekStart:
		// OK
	case io.SeekCurrent:
		 += .Offset
	case io.SeekEnd:
		 += .Length
	default:
		return 0, errors.New("httprange: invalid seek whence")
	}
	if  < 0 ||  > .Length {
		return 0, errors.New("httprange: invalid seek offset")
	}
	.Offset = 
	return , nil
}

// Close releases resources associated with the reader and cancels any pending
// range requests with [BytesResourceReaderClosedError] cause.
// After Close returns, all subsequent operations on the reader will fail.
func ( *BytesResourceReader) () error {
	.Cancel(errBytesResourceReaderClosed)
	return nil
}