package pgdialect

import (
	
	
	
	

	
	
)

const (
	// Date / Time
	pgTypeTimestampTz = "TIMESTAMPTZ"         // Timestamp with a time zone
	pgTypeDate        = "DATE"                // Date
	pgTypeTime        = "TIME"                // Time without a time zone
	pgTypeTimeTz      = "TIME WITH TIME ZONE" // Time with a time zone
	pgTypeInterval    = "INTERVAL"            // Time Interval

	// Network Addresses
	pgTypeInet    = "INET"    // IPv4 or IPv6 hosts and networks
	pgTypeCidr    = "CIDR"    // IPv4 or IPv6 networks
	pgTypeMacaddr = "MACADDR" // MAC addresses

	// Serial Types
	pgTypeSmallSerial = "SMALLSERIAL" // 2 byte autoincrementing integer
	pgTypeSerial      = "SERIAL"      // 4 byte autoincrementing integer
	pgTypeBigSerial   = "BIGSERIAL"   // 8 byte autoincrementing integer

	// Character Types
	pgTypeChar = "CHAR" // fixed length string (blank padded)
	pgTypeText = "TEXT" // variable length string without limit

	// JSON Types
	pgTypeJSON  = "JSON"  // text representation of json data
	pgTypeJSONB = "JSONB" // binary representation of json data

	// Binary Data Types
	pgTypeBytea = "BYTEA" // binary string
)

var (
	timeType           = reflect.TypeOf((*time.Time)(nil)).Elem()
	ipType             = reflect.TypeOf((*net.IP)(nil)).Elem()
	ipNetType          = reflect.TypeOf((*net.IPNet)(nil)).Elem()
	jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
)

func ( *schema.Field) string {
	if .UserSQLType != "" {
		return .UserSQLType
	}

	if ,  := .Tag.Options["composite"];  {
		return 
	}

	if ,  := .Tag.Options["hstore"];  {
		return "hstore"
	}

	if ,  := .Tag.Options["array"];  {
		switch .IndirectType.Kind() {
		case reflect.Slice, reflect.Array:
			 := sqlType(.IndirectType.Elem())
			return  + "[]"
		}
	}

	return sqlType(.IndirectType)
}

func ( reflect.Type) string {
	switch  {
	case ipType:
		return pgTypeInet
	case ipNetType:
		return pgTypeCidr
	case jsonRawMessageType:
		return pgTypeJSONB
	}

	 := schema.DiscoverSQLType()
	switch  {
	case sqltype.Timestamp:
		 = pgTypeTimestampTz
	}

	switch .Kind() {
	case reflect.Map, reflect.Struct:
		if  == sqltype.VarChar {
			return pgTypeJSONB
		}
		return 
	case reflect.Array, reflect.Slice:
		if .Elem().Kind() == reflect.Uint8 {
			return pgTypeBytea
		}
		return pgTypeJSONB
	}

	return 
}