package httprange

import (
	
	
	
	
	
	
	
)

const bytesUnit = "bytes"

// BytesSpecifier constructs a byte range specifier from a sequence of positions.
//
// The positions are interpreted as follows:
//   - An empty sequence produces the unsatisfiable range "-0".
//   - A negative integer N produces a suffix-range "-N".
//   - A non-negative integer N followed by a smaller or
//     negative integer produces an open range "N-".
//   - Two adjacent non-negative integers M, N where M ≤ N
//     produce a closed range "M-N".
//
// It preserves input order even if it produces overlapping ranges or ranges are
// not strictly in ascending order.
func ( ...int64) Specifier {
	if len() == 0 {
		return bytesUnit + "=-0" // unsatisfiable
	}
	 := []byte(bytesUnit + "=")
	for  := 0;  < len(); ++ {
		if  != 0 {
			 = append(, ',')
		}

		 := []

		 = strconv.AppendInt(, , 10)

		if  < 0 {
			continue
		}

		 = append(, '-')

		 :=  + 1
		if  == len() {
			break
		}

		 := []
		if  >=  {
			 = 
			 = strconv.AppendInt(, , 10)
			if +1 == len() {
				break
			}
		}
	}
	return Specifier()
}

// BytesReader implements [io.ReaderAt] for reading byte ranges from a [Ranger].
type BytesReader struct {
	// Context is the context to use for Ranger.Range calls.
	Context context.Context

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

// ReadAt reads len(p) bytes starting at byte offset off. It performs a byte
// range request for the range [off, off+len(p)-1] and reads the response into
// p. It returns [io.EOF] if the range cannot be satisfied.
func ( *BytesReader) ( []byte,  int64) (int, error) {
	if  < 0 {
		return 0, errors.New("httprange: negative read offset")
	}
	if len() == 0 {
		return 0, nil
	}
	if  > math.MaxInt64-int64(len())+1 {
		return 0, errors.New("httprange: read offset overflow")
	}

	,  := , +int64(len())-1
	 := BytesSpecifier(, )

	,  := context.WithCancel(.Context)
	,  := iter.Pull2(.Ranger.Range(, ))
	defer ()
	defer ()

	, ,  := ()
	if ! {
		return 0, errors.New("rangeio: empty sequence")
	}
	if  != nil {
		var  *UnsatisfiedRangeError
		if errors.As(, &) {
			// Assume EOF if complete length is unknown.
			if .Resp == "" {
				return 0, io.EOF
			}

			,  := parseUnsatisfiedRangeResp(.Resp)
			if ! {
				return 0, fmt.Errorf(
					"httprange: invalid unsatisfied range %q",
					.Resp,
				)
			}

			if  < .CompleteLength {
				return 0, fmt.Errorf(
					"httprange: unexpected unsatisfied range %q (first byte %d is satisfiable)",
					.Resp, ,
				)
			}

			return 0, io.EOF
		}
		return 0, 
	}

	,  := parseBytesRangeResp(.Resp)
	if ! {
		return 0, fmt.Errorf(
			"httprange: invalid bytes range %q",
			.Resp,
		)
	}
	if .First !=  {
		return 0, fmt.Errorf(
			"httprange: unexpected first byte position %d (expected %d)",
			.First, ,
		)
	}
	if .Last >  || .Last <  && .CompleteLength > 0 && .Last != .CompleteLength-1 {
		return 0, fmt.Errorf(
			"httprange: unexpected last byte position %d (expected %d or less at EOF)",
			.Last, ,
		)
	}

	 := int(.Last - .First + 1) // 0 < rangeLength ≤ len(p)
	 := .CompleteLength > 0 && .Last == .CompleteLength-1

	var ,  int
	for  <  &&  == nil {
		,  = .Reader.Read([:])
		 += 
	}
	if  ==  &&  == nil {
		var  [1]byte // for EOF
		,  = .Reader.Read([:])
		 += 
	}
	if  !=  {
		return 0, fmt.Errorf(
			"httprange: invalid range length %d (read %d bytes)",
			, ,
		)
	}

	switch {
	case  &&  == nil:
		 = io.EOF
	case ! &&  == io.EOF:
		 = nil
	}

	() // unblock reading response body
	if , ,  := ();  {
		return 0, errors.New("httprange: unexpected multiple ranges")
	}

	return , 
}