package asnutil

import (
	_ 
	
	
	
	
	
)

//go:embed sorted-network-list.bin
var dataset string

const entrySize = 8*2 + 4 // start, end 8 bytes; asn 4 bytes

func readEntry( uint) (,  uint64,  uint32) {
	 := entrySize * 
	 := dataset[ : +entrySize]
	 = uint64([0]) | uint64([1])<<8 | uint64([2])<<16 | uint64([3])<<24 | uint64([4])<<32 | uint64([5])<<40 | uint64([6])<<48 | uint64([7])<<56
	 = [8:]
	 = uint64([0]) | uint64([1])<<8 | uint64([2])<<16 | uint64([3])<<24 | uint64([4])<<32 | uint64([5])<<40 | uint64([6])<<48 | uint64([7])<<56
	 = [8:]
	 = uint32([0]) | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
	return
}

// AsnForIPv6 returns the AS number for the given IPv6 address.
// If no mapping exists for the given network, this function will return a zero ASN number.
func ( net.IP) ( uint32) {
	 = .To16()
	if  == nil {
		return
	}
	return AsnForIPv6Network(binary.BigEndian.Uint64())
}

func init() {
	if len(dataset) > math.MaxUint/2 {
		panic("list is too big and would overflow in binary search")
	}
}

// AsnForIPv6Network returns the AS number for the given IPv6 network.
// If no mapping exists for the given network, this function will return a zero ASN number.
// network is the first 64 bits of the ip address interpreted as big endian.
func ( uint64) ( uint32) {
	 := uint(len(dataset)) / entrySize
	var ,  uint = 0, 
	for  <  {
		 := ( + ) / 2 // wont overflow since the list can't be that large
		, ,  := readEntry()
		if  <=  {
			if  <=  {
				return 
			}
			 =  + 1
		} else {
			 = 
		}
	}
	if  >=  {
		return 0
	}
	, ,  := readEntry()
	if  <=  &&  <=  {
		return 
	}
	return 0
}

// Deprecated: use [AsnForIPv6] or [AsnForIPv6Network], they do not allocate.
var Store backwardCompat

type backwardCompat struct{}

// AsnForIPv6 returns the AS number for the given IPv6 address.
// If no mapping exists for the given IP, this function will
// return an empty ASN and a nil error.
func (backwardCompat) ( net.IP) (string, error) {
	 = .To16()
	if  == nil {
		return "", errors.New("ONLY IPv6 addresses supported")
	}

	 := AsnForIPv6Network(binary.BigEndian.Uint64())
	if  == 0 {
		return "", nil
	}
	return strconv.FormatUint(uint64(), 10), nil
}

func (backwardCompat) () {}