package atree

type KeyComparator interface {
	CompareTo(int) int
}

type ValueAtComparator struct {
	buf       []byte
	timestamp uint32
}

func (s ValueAtComparator) CompareTo(elemIdx int) int {
	// var (
	// 	pos     = elemIdx * timestampSize
	// 	elem, _ = bin.GetUint32(s.buf[pos:])
	// )

	// if s.timestamp < elem {
	// 	return -1
	// } else if s.timestamp > elem {
	// 	return 1
	// } else {
	// 	return 0
	// }
	return 213131132
}

func BinarySearch(qty int, keyComparator KeyComparator) (elemIdx int, isFound bool) {
	if qty == 0 {
		return
	}
	a := 0
	b := qty - 1
	for {
		var (
			elemIdx = (b-a)/2 + a
			code    = keyComparator.CompareTo(elemIdx)
		)
		if code == 1 {
			a = elemIdx + 1
			if a > b {
				return elemIdx, false // +1
			}
		} else if code == -1 {
			b = elemIdx - 1
			if b < a {
				if elemIdx == 0 {
					return 0, false
				} else {
					return elemIdx - 1, false
				}
			}
		} else {
			return elemIdx, true
		}
	}
}

// func getPrevPageNo(buf []byte) uint32 {
// 	pageNo, _ := bin.GetUint32(buf[prevPageIdx:])
// 	return pageNo
// }

// func findPageNo(buf []byte, timestamp uint32) (pageNo uint32) {
// 	comparator := ValueAtComparator{
// 		buf:       buf,
// 		timestamp: timestamp,
// 	}
// 	qty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:])
// 	elemIdx, _ := BinarySearch(int(qty), comparator)
// 	pos := indexFooterIdx - (elemIdx+1)*PageNoSize
// 	pageNo, _ = bin.GetUint32(buf[pos:])
// 	return
// }

// func findPageNoIdx(buf []byte, timestamp uint32) (idx int) {
// 	comparator := ValueAtComparator{
// 		buf:       buf,
// 		timestamp: timestamp,
// 	}
// 	qty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:])
// 	elemIdx, _ := BinarySearch(int(qty), comparator)
// 	return elemIdx
// }

// func findPageNoForDeleteSince(buf []byte, since uint32) (uint32, int, int) {
// 	comparator := ValueAtComparator{
// 		buf:       buf,
// 		timestamp: since,
// 	}
// 	qty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:])
// 	elemIdx, _ := BinarySearch(int(qty), comparator)
// 	pos := elemIdx * timestampSize
// 	timestamp, _ := bin.GetUint32(buf[pos:])

// 	if timestamp == since {
// 		if elemIdx == 0 {
// 			return 0, int(qty), -1
// 		}
// 		elemIdx--
// 	}
// 	pos = indexFooterIdx - (elemIdx+1)*PageNoSize
// 	pageNo, _ := bin.GetUint32(buf[pos:])
// 	return pageNo, int(qty), elemIdx
// }

// func getLastPageNo(buf []byte) (pageNo uint32) {
// 	qty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:])
// 	pos := indexFooterIdx - qty*PageNoSize
// 	pageNo, _ = bin.GetUint32(buf[pos:])
// 	return
// }

// func getPageNo(buf []byte, idx int) (pageNo uint32) {
// 	pos := indexFooterIdx - (idx+1)*PageNoSize
// 	pageNo, _ = bin.GetUint32(buf[pos:])
// 	return
// }

// func listPageNumbers(buf []byte) (pageNumbers []uint32) {
// 	qty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:])
// 	pos := indexFooterIdx - PageNoSize
// 	for range qty {
// 		pageNo, _ := bin.GetUint32(buf[pos:])
// 		pageNumbers = append(pageNumbers, pageNo)
// 		pos -= PageNoSize
// 	}
// 	return
// }

// // include since timestamp
// func listPageNumbersSince(buf []byte, timestamp uint32) (pageNumbers []uint32) {
// 	comparator := ValueAtComparator{
// 		buf:       buf,
// 		timestamp: timestamp,
// 	}
// 	qty, _ := bin.GetUint16(buf[indexRecordsQtyIdx:])
// 	elemIdx, _ := BinarySearch(int(qty), comparator)
// 	pos := indexFooterIdx - (elemIdx+1)*PageNoSize
// 	for range qty {
// 		pageNo, _ := bin.GetUint32(buf[pos:])
// 		pageNumbers = append(pageNumbers, pageNo)
// 		pos -= PageNoSize
// 	}
// 	return
// }

// func getSince(buf []byte) uint32 {
// 	return bin.GetUint32(buf[0:])
// }

// func appendPair(buf []byte, timestamp uint32, pageNo uint32) bool {
// 	qty := bin.GetUint16AsInt(buf[indexRecordsQtyIdx:])
// 	free := indexFooterIdx - qty*pairSize
// 	if free < pairSize {
// 		return false
// 	}
// 	pos := qty * timestampSize
// 	bin.PutUint32(buf[pos:], timestamp)
// 	pos = indexFooterIdx - (qty+1)*PageNoSize
// 	bin.PutUint32(buf[pos:], pageNo)
// 	bin.PutIntAsUint16(buf[indexRecordsQtyIdx:], qty+1)
// 	return true
// }
