package filterlist

import "github.com/AdguardTeam/urlfilter/rules"

// RuleStorageScanner scans multiple RuleScanner instances.  The rule index is
// built from the rule index in the list + the list ID.  First 4 bytes is the
// rule index in the list, second 4 bytes is the list ID.
type RuleStorageScanner struct {
	// currentScanner is the scanner currently in use by RuleStorageScanner.
	currentScanner *RuleScanner

	// Scanners is the list of list scanners backing this combined scanner,
	Scanners []*RuleScanner

	// currentScannerIdx is the index of the current scanner.
	currentScannerIdx int
}

// Scan advances the RuleStorageScanner to the next rule, which will then be
// available through the Rule method.  It returns false when the scan stops,
// either by reaching the end of the input or an error.
func (s *RuleStorageScanner) Scan() (ok bool) {
	if len(s.Scanners) == 0 {
		return false
	}

	if s.currentScanner == nil {
		s.currentScannerIdx = 0
		s.currentScanner = s.Scanners[s.currentScannerIdx]
	}

	for {
		scan := s.currentScanner.Scan()
		if scan {
			return true
		}

		// Take the next scanner or just return false if there's nothing more
		if s.currentScannerIdx == (len(s.Scanners) - 1) {
			return false
		}

		s.currentScannerIdx++
		s.currentScanner = s.Scanners[s.currentScannerIdx]
	}
}

// Rule returns the most recent rule generated by a call to
// [*RuleStorageScanner.Scan], if any, and the ID of this rule.
func (s *RuleStorageScanner) Rule() (r rules.Rule, id StorageID) {
	if s.currentScanner == nil {
		return nil, StorageID{}
	}

	f, idx := s.currentScanner.Rule()
	if f == nil {
		return nil, StorageID{}
	}

	return f, NewStorageID(rules.ListID(f.GetFilterListID()), idx)
}
