package storage

import (
	"bytes"

	bin "gordenko.dev/dima/bin/little"
)

const recordSize = 8
const chunkSize = 24

func copyPayloadFromChunks(w *bytes.Buffer, chunks [][]byte, size int, offset int) {
	bin.WriteUint16(w, uint16(size))
	var (
		chunkIdx = offset / chunkSize
		byteIdx  = offset % chunkSize
	)
	for _, chunk := range chunks[chunkIdx:] {
		available := len(chunk) - byteIdx
		if available <= size {
			w.Write(chunk[byteIdx:])
			size -= available
			if size == 0 {
				return
			}
			byteIdx = 0
		} else {
			w.Write(chunk[byteIdx : byteIdx+size])
			return
		}
	}
}

/////////////////////////////////////////

// type DataPage struct {
// 	PageNo     uint32
// 	Reused     bool
// 	PrevPageNo uint32
// 	Checksum   uint32
// 	Timestamps []byte
// 	Values     []byte
// }

// type IndexPage struct {
// 	PageNo   uint32
// 	Reused   bool
// 	Checksum uint32
// 	Records  []byte
// }

// type IndexLevel struct {
// 	Pages   []IndexPage
// 	Records []byte // unfilled
// }

// Для декодінга
// type TxAppendedMeasures struct {
// 	MetricID  uint32
// 	DataPages []DataPage
// 	// offsets потрібні тому що дані не додаються в кінець, а перезаписують кілька
// 	// останніх байтів unfilled даних. Потрібно для коректного recovery.
// 	// Якщо є DataPages, то застосовуються для 1-ї Data сторінки, інакше - до timestamps і values (unfilled)
// 	TimestampsOffset int
// 	ValuesOffset     int
// 	Timestamps       []byte // unfilled
// 	Values           []byte // unfilled
// 	IndexLevels      []IndexLevel
// }

// func (s *TxAppendedMeasures) Read(r *bytes.Buffer) (err error) {
// 	s.MetricID, err = bin.ReadUint32(r)
// 	if err != nil {
// 		return
// 	}
// 	dataPagesQty, err := bin.ReadVarSize(r)
// 	if err != nil {
// 		return
// 	}
// 	for range dataPagesQty {
// 		var (
// 			p                          DataPage
// 			timestampsSize, valuesSize int
// 			//b byte
// 		)
// 		p.PageNo, err = bin.ReadUint32(r)
// 		if err != nil {
// 			return
// 		}
// 		p.Reused, err = bin.ReadBool(r)
// 		if err != nil {
// 			return
// 		}
// 		p.PrevPageNo, err = bin.ReadUint32(r)
// 		if err != nil {
// 			return
// 		}
// 		p.Checksum, err = bin.ReadUint32(r)
// 		if err != nil {
// 			return
// 		}
// 		timestampsSize, err = bin.ReadUint16AsInt(r)
// 		if err != nil {
// 			return
// 		}
// 		p.Timestamps, err = bin.ReadN(r, timestampsSize)
// 		if err != nil {
// 			return
// 		}
// 		valuesSize, err = bin.ReadUint16AsInt(r)
// 		if err != nil {
// 			return
// 		}
// 		p.Values, err = bin.ReadN(r, valuesSize)
// 		if err != nil {
// 			return
// 		}
// 		s.DataPages = append(s.DataPages, p)
// 	}
// 	s.TimestampsOffset, err = bin.ReadUint16AsInt(r)
// 	if err != nil {
// 		return
// 	}
// 	s.ValuesOffset, err = bin.ReadUint16AsInt(r)
// 	if err != nil {
// 		return
// 	}
// 	var (
// 		timestampsSize, valuesSize int
// 	)
// 	timestampsSize, err = bin.ReadVarSize(r)
// 	if err != nil {
// 		return
// 	}
// 	s.Timestamps, err = bin.ReadN(r, timestampsSize)
// 	if err != nil {
// 		return
// 	}
// 	valuesSize, err = bin.ReadVarSize(r)
// 	if err != nil {
// 		return
// 	}
// 	s.Values, err = bin.ReadN(r, valuesSize)
// 	if err != nil {
// 		return
// 	}
// 	if len(s.DataPages) == 0 {
// 		return
// 	}
// 	indexLevelsQty, err := bin.ReadVarSize(r)
// 	if err != nil {
// 		return
// 	}
// 	for range indexLevelsQty {
// 		var (
// 			indexPagesQty int
// 			level         IndexLevel
// 			recordsQty    int
// 		)
// 		indexPagesQty, err = bin.ReadVarSize(r)
// 		if err != nil {
// 			return
// 		}
// 		for range indexPagesQty {
// 			var (
// 				p          IndexPage
// 				recordsQty int
// 			)
// 			p.PageNo, err = bin.ReadUint32(r)
// 			if err != nil {
// 				return
// 			}
// 			p.Reused, err = bin.ReadBool(r)
// 			if err != nil {
// 				return
// 			}
// 			p.Checksum, err = bin.ReadUint32(r)
// 			if err != nil {
// 				return
// 			}
// 			recordsQty, err = bin.ReadVarSize(r)
// 			if err != nil {
// 				return
// 			}
// 			p.Records, err = bin.ReadN(r, recordsQty*recordSize)
// 			if err != nil {
// 				return
// 			}
// 			level.Pages = append(level.Pages, p)
// 		}
// 		recordsQty, err = bin.ReadVarSize(r)
// 		if err != nil {
// 			return
// 		}
// 		level.Records, err = bin.ReadN(r, recordsQty*recordSize)
// 		if err != nil {
// 			return
// 		}
// 		s.IndexLevels = append(s.IndexLevels, level)
// 	}
// 	return
// }
