package pgtype

import (
	
	
	
)

type BoundType byte

const (
	Inclusive = BoundType('i')
	Exclusive = BoundType('e')
	Unbounded = BoundType('U')
	Empty     = BoundType('E')
)

func ( BoundType) () string {
	return string()
}

type untypedTextRange struct {
	Lower     string
	Upper     string
	LowerType BoundType
	UpperType BoundType
}

func parseUntypedTextRange( string) (*untypedTextRange, error) {
	 := &untypedTextRange{}
	if  == "empty" {
		.LowerType = Empty
		.UpperType = Empty
		return , nil
	}

	 := bytes.NewBufferString()

	skipWhitespace()

	, ,  := .ReadRune()
	if  != nil {
		return nil, fmt.Errorf("invalid lower bound: %v", )
	}
	switch  {
	case '(':
		.LowerType = Exclusive
	case '[':
		.LowerType = Inclusive
	default:
		return nil, fmt.Errorf("missing lower bound, instead got: %v", string())
	}

	, _,  = .ReadRune()
	if  != nil {
		return nil, fmt.Errorf("invalid lower value: %v", )
	}
	.UnreadRune()

	if  == ',' {
		.LowerType = Unbounded
	} else {
		.Lower,  = rangeParseValue()
		if  != nil {
			return nil, fmt.Errorf("invalid lower value: %v", )
		}
	}

	, _,  = .ReadRune()
	if  != nil {
		return nil, fmt.Errorf("missing range separator: %v", )
	}
	if  != ',' {
		return nil, fmt.Errorf("missing range separator: %v", )
	}

	, _,  = .ReadRune()
	if  != nil {
		return nil, fmt.Errorf("invalid upper value: %v", )
	}

	if  == ')' ||  == ']' {
		.UpperType = Unbounded
	} else {
		.UnreadRune()
		.Upper,  = rangeParseValue()
		if  != nil {
			return nil, fmt.Errorf("invalid upper value: %v", )
		}

		, _,  = .ReadRune()
		if  != nil {
			return nil, fmt.Errorf("missing upper bound: %v", )
		}
		switch  {
		case ')':
			.UpperType = Exclusive
		case ']':
			.UpperType = Inclusive
		default:
			return nil, fmt.Errorf("missing upper bound, instead got: %v", string())
		}
	}

	skipWhitespace()

	if .Len() > 0 {
		return nil, fmt.Errorf("unexpected trailing data: %v", .String())
	}

	return , nil
}

func rangeParseValue( *bytes.Buffer) (string, error) {
	, ,  := .ReadRune()
	if  != nil {
		return "", 
	}
	if  == '"' {
		return rangeParseQuotedValue()
	}
	.UnreadRune()

	 := &bytes.Buffer{}

	for {
		, ,  := .ReadRune()
		if  != nil {
			return "", 
		}

		switch  {
		case '\\':
			, _,  = .ReadRune()
			if  != nil {
				return "", 
			}
		case ',', '[', ']', '(', ')':
			.UnreadRune()
			return .String(), nil
		}

		.WriteRune()
	}
}

func rangeParseQuotedValue( *bytes.Buffer) (string, error) {
	 := &bytes.Buffer{}

	for {
		, ,  := .ReadRune()
		if  != nil {
			return "", 
		}

		switch  {
		case '\\':
			, _,  = .ReadRune()
			if  != nil {
				return "", 
			}
		case '"':
			, _,  = .ReadRune()
			if  != nil {
				return "", 
			}
			if  != '"' {
				.UnreadRune()
				return .String(), nil
			}
		}
		.WriteRune()
	}
}

type untypedBinaryRange struct {
	Lower     []byte
	Upper     []byte
	LowerType BoundType
	UpperType BoundType
}

// 0 = ()      = 00000
// 1 = empty   = 00001
// 2 = [)      = 00010
// 4 = (]      = 00100
// 6 = []      = 00110
// 8 = )       = 01000
// 12 = ]      = 01100
// 16 = (      = 10000
// 18 = [      = 10010
// 24 =        = 11000

const emptyMask = 1
const lowerInclusiveMask = 2
const upperInclusiveMask = 4
const lowerUnboundedMask = 8
const upperUnboundedMask = 16

func parseUntypedBinaryRange( []byte) (*untypedBinaryRange, error) {
	 := &untypedBinaryRange{}

	if len() == 0 {
		return nil, fmt.Errorf("range too short: %v", len())
	}

	 := [0]
	 := 1

	if &emptyMask > 0 {
		if len([:]) > 0 {
			return nil, fmt.Errorf("unexpected trailing bytes parsing empty range: %v", len([:]))
		}
		.LowerType = Empty
		.UpperType = Empty
		return , nil
	}

	if &lowerInclusiveMask > 0 {
		.LowerType = Inclusive
	} else if &lowerUnboundedMask > 0 {
		.LowerType = Unbounded
	} else {
		.LowerType = Exclusive
	}

	if &upperInclusiveMask > 0 {
		.UpperType = Inclusive
	} else if &upperUnboundedMask > 0 {
		.UpperType = Unbounded
	} else {
		.UpperType = Exclusive
	}

	if .LowerType == Unbounded && .UpperType == Unbounded {
		if len([:]) > 0 {
			return nil, fmt.Errorf("unexpected trailing bytes parsing unbounded range: %v", len([:]))
		}
		return , nil
	}

	if len([:]) < 4 {
		return nil, fmt.Errorf("too few bytes for size: %v", [:])
	}
	 := int(binary.BigEndian.Uint32([:]))
	 += 4

	 := [ : +]
	 += 

	if .LowerType != Unbounded {
		.Lower = 
	} else {
		.Upper = 
		if len([:]) > 0 {
			return nil, fmt.Errorf("unexpected trailing bytes parsing range: %v", len([:]))
		}
		return , nil
	}

	if .UpperType != Unbounded {
		if len([:]) < 4 {
			return nil, fmt.Errorf("too few bytes for size: %v", [:])
		}
		 := int(binary.BigEndian.Uint32([:]))
		 += 4
		.Upper = [ : +]
		 += 
	}

	if len([:]) > 0 {
		return nil, fmt.Errorf("unexpected trailing bytes parsing range: %v", len([:]))
	}

	return , nil

}

// Range is a generic range type.
type Range[ any] struct {
	Lower     
	Upper     
	LowerType BoundType
	UpperType BoundType
	Valid     bool
}

func ( Range[]) () bool {
	return !.Valid
}

func ( Range[]) () (,  BoundType) {
	return .LowerType, .UpperType
}

func ( Range[]) () (,  any) {
	return &.Lower, &.Upper
}

func ( *Range[]) () error {
	* = Range[]{}
	return nil
}

func ( *Range[]) () (,  any) {
	return &.Lower, &.Upper
}

func ( *Range[]) (,  BoundType) error {
	if  == Unbounded ||  == Empty {
		var  
		.Lower = 
	}
	if  == Unbounded ||  == Empty {
		var  
		.Upper = 
	}
	.LowerType = 
	.UpperType = 
	.Valid = true
	return nil
}