package shared

import "gitea.maximumdirect.net/eric/notarius/internal/core/source"

// ChunkCoverage is an immutable snapshot of the source units materialized in
// one extraction chunk.
type ChunkCoverage struct {
	sourceID string
	unitIDs  map[int]struct{}
}

// NewChunkCoverage snapshots chunk without retaining or mutating it.
func NewChunkCoverage(chunk *source.Chunk) ChunkCoverage {
	if chunk == nil {
		return ChunkCoverage{}
	}
	coverage := ChunkCoverage{
		sourceID: chunk.SourceID,
		unitIDs:  make(map[int]struct{}, len(chunk.Units)),
	}
	for _, unit := range chunk.Units {
		coverage.unitIDs[unit.ID] = struct{}{}
	}
	return coverage
}

// Contains reports whether ref identifies a valid inclusive span in index and
// every unit in that document-ordered span is present in the chunk snapshot.
func (c ChunkCoverage) Contains(index source.DocumentIndex, doc *source.SourceDocument, ref source.SourceRef) bool {
	documentID, ok := index.DocumentID()
	if !ok || doc == nil || doc.ID != documentID || c.sourceID == "" || ref.SourceID != c.sourceID || ref.SourceID != documentID {
		return false
	}
	start, startOK := index.Position(ref.StartUnitID)
	end, endOK := index.Position(ref.EndUnitID)
	if !startOK || !endOK || start > end {
		return false
	}
	for position := start; position <= end; position++ {
		if position >= len(doc.Units) {
			return false
		}
		if _, found := c.unitIDs[doc.Units[position].ID]; !found {
			return false
		}
	}
	return true
}
