package storage

import (
	"errors"
	"math"
	"os"

	"gordenko.dev/dima/qb/freelist"
)

type PageNoProvider struct {
	freeList   *freelist.FreeList
	pagesCount uint32
}

type PageNoProviderOptions struct {
	FilePath string
	PageSize int
	FreeList *freelist.FreeList
}

func NewPageNoProvider(opt PageNoProviderOptions) (_ *PageNoProvider, err error) {
	if opt.FreeList == nil {
		return nil, errors.New("FreeList option is required")
	}
	file, err := os.Open(opt.FilePath)
	if err != nil {
		return
	}
	defer file.Close()
	info, err := file.Stat()
	if err != nil {
		return
	}
	pagesCount := info.Size() / int64(opt.PageSize)
	return &PageNoProvider{
		freeList:   opt.FreeList,
		pagesCount: uint32(pagesCount),
	}, nil
}

func (s *PageNoProvider) GetPageNumber() (uint32, bool, error) {
	pageNo, err := s.freeList.GetPageNumber()
	if err != nil {
		return 0, false, err
	}
	if pageNo > 0 {
		return pageNo, true, nil
	}
	if s.pagesCount < math.MaxUint32 {
		s.pagesCount++
		return s.pagesCount, false, nil
	}
	return 0, false, errors.New("no space")
}
