package pgtype

import (
	
	
	
)

type JSONBCodec struct{}

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

func (JSONBCodec) () int16 {
	return TextFormatCode
}

func (JSONBCodec) ( *Map,  uint32,  int16,  any) EncodePlan {
	switch  {
	case BinaryFormatCode:
		 := JSONCodec{}.PlanEncode(, , TextFormatCode, )
		if  != nil {
			return &encodePlanJSONBCodecBinaryWrapper{textPlan: }
		}
	case TextFormatCode:
		return JSONCodec{}.PlanEncode(, , , )
	}

	return nil
}

type encodePlanJSONBCodecBinaryWrapper struct {
	textPlan EncodePlan
}

func ( *encodePlanJSONBCodecBinaryWrapper) ( any,  []byte) ( []byte,  error) {
	 = append(, 1)
	return .textPlan.Encode(, )
}

func (JSONBCodec) ( *Map,  uint32,  int16,  any) ScanPlan {
	switch  {
	case BinaryFormatCode:
		 := JSONCodec{}.PlanScan(, , TextFormatCode, )
		if  != nil {
			return &scanPlanJSONBCodecBinaryUnwrapper{textPlan: }
		}
	case TextFormatCode:
		return JSONCodec{}.PlanScan(, , , )
	}

	return nil
}

type scanPlanJSONBCodecBinaryUnwrapper struct {
	textPlan ScanPlan
}

func ( *scanPlanJSONBCodecBinaryUnwrapper) ( []byte,  any) error {
	if  == nil {
		return .textPlan.Scan(, )
	}

	if len() == 0 {
		return fmt.Errorf("jsonb too short")
	}

	if [0] != 1 {
		return fmt.Errorf("unknown jsonb version number %d", [0])
	}

	return .textPlan.Scan([1:], )
}

func ( JSONBCodec) ( *Map,  uint32,  int16,  []byte) (driver.Value, error) {
	if  == nil {
		return nil, nil
	}

	switch  {
	case BinaryFormatCode:
		if len() == 0 {
			return nil, fmt.Errorf("jsonb too short")
		}

		if [0] != 1 {
			return nil, fmt.Errorf("unknown jsonb version number %d", [0])
		}

		 := make([]byte, len()-1)
		copy(, [1:])
		return , nil
	case TextFormatCode:
		 := make([]byte, len())
		copy(, )
		return , nil
	default:
		return nil, fmt.Errorf("unknown format code: %v", )
	}
}

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

	switch  {
	case BinaryFormatCode:
		if len() == 0 {
			return nil, fmt.Errorf("jsonb too short")
		}

		if [0] != 1 {
			return nil, fmt.Errorf("unknown jsonb version number %d", [0])
		}

		 = [1:]
	case TextFormatCode:
	default:
		return nil, fmt.Errorf("unknown format code: %v", )
	}

	var  any
	 := json.Unmarshal(, &)
	return , 
}