package pgtype

import (
	
	
	

	
)

type BitsScanner interface {
	ScanBits(v Bits) error
}

type BitsValuer interface {
	BitsValue() (Bits, error)
}

// Bits represents the PostgreSQL bit and varbit types.
type Bits struct {
	Bytes []byte
	Len   int32 // Number of bits
	Valid bool
}

func ( *Bits) ( Bits) error {
	* = 
	return nil
}

func ( Bits) () (Bits, error) {
	return , nil
}

// Scan implements the database/sql Scanner interface.
func ( *Bits) ( any) error {
	if  == nil {
		* = Bits{}
		return nil
	}

	switch src := .(type) {
	case string:
		return scanPlanTextAnyToBitsScanner{}.Scan([]byte(), )
	}

	return fmt.Errorf("cannot scan %T", )
}

// Value implements the database/sql/driver Valuer interface.
func ( Bits) () (driver.Value, error) {
	if !.Valid {
		return nil, nil
	}

	,  := BitsCodec{}.PlanEncode(nil, 0, TextFormatCode, ).Encode(, nil)
	if  != nil {
		return nil, 
	}
	return string(), 
}

type BitsCodec struct{}

func (BitsCodec) ( int16) bool {
	return  == TextFormatCode ||  == BinaryFormatCode
}

func (BitsCodec) () int16 {
	return BinaryFormatCode
}

func (BitsCodec) ( *Map,  uint32,  int16,  any) EncodePlan {
	if ,  := .(BitsValuer); ! {
		return nil
	}

	switch  {
	case BinaryFormatCode:
		return encodePlanBitsCodecBinary{}
	case TextFormatCode:
		return encodePlanBitsCodecText{}
	}

	return nil
}

type encodePlanBitsCodecBinary struct{}

func (encodePlanBitsCodecBinary) ( any,  []byte) ( []byte,  error) {
	,  := .(BitsValuer).BitsValue()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	 = pgio.AppendInt32(, .Len)
	return append(, .Bytes...), nil
}

type encodePlanBitsCodecText struct{}

func (encodePlanBitsCodecText) ( any,  []byte) ( []byte,  error) {
	,  := .(BitsValuer).BitsValue()
	if  != nil {
		return nil, 
	}

	if !.Valid {
		return nil, nil
	}

	for  := int32(0);  < .Len; ++ {
		 :=  / 8
		 := byte(128 >> byte(%8))
		 := byte('0')
		if .Bytes[]& > 0 {
			 = '1'
		}
		 = append(, )
	}

	return , nil
}

func (BitsCodec) ( *Map,  uint32,  int16,  any) ScanPlan {

	switch  {
	case BinaryFormatCode:
		switch .(type) {
		case BitsScanner:
			return scanPlanBinaryBitsToBitsScanner{}
		}
	case TextFormatCode:
		switch .(type) {
		case BitsScanner:
			return scanPlanTextAnyToBitsScanner{}
		}
	}

	return nil
}

func ( BitsCodec) ( *Map,  uint32,  int16,  []byte) (driver.Value, error) {
	return codecDecodeToTextFormat(, , , , )
}

func ( BitsCodec) ( *Map,  uint32,  int16,  []byte) (any, error) {
	if  == nil {
		return nil, nil
	}

	var  Bits
	 := codecScan(, , , , , &)
	if  != nil {
		return nil, 
	}
	return , nil
}

type scanPlanBinaryBitsToBitsScanner struct{}

func (scanPlanBinaryBitsToBitsScanner) ( []byte,  any) error {
	 := ().(BitsScanner)

	if  == nil {
		return .ScanBits(Bits{})
	}

	if len() < 4 {
		return fmt.Errorf("invalid length for bit/varbit: %v", len())
	}

	 := int32(binary.BigEndian.Uint32())
	 := 4

	return .ScanBits(Bits{Bytes: [:], Len: , Valid: true})
}

type scanPlanTextAnyToBitsScanner struct{}

func (scanPlanTextAnyToBitsScanner) ( []byte,  any) error {
	 := ().(BitsScanner)

	if  == nil {
		return .ScanBits(Bits{})
	}

	 := len()
	 :=  / 8
	if %8 > 0 {
		++
	}
	 := make([]byte, )

	for ,  := range  {
		if  == '1' {
			 :=  / 8
			 := uint( % 8)
			[] = [] | (128 >> )
		}
	}

	return .ScanBits(Bits{Bytes: , Len: int32(), Valid: true})
}