package internal

type Customer struct {
	EMail     string
	Interests []string
}

func (c Customer) HasInterest(interest string) bool {
	for _, customerInterest := range c.Interests {
		if customerInterest == interest {
			return true
		}
	}
	return false
}

type CustomerIterator interface {
	First() *Customer
	Next() *Customer
	IsDone() bool
	CurrentItem() *Customer
}

type InterestFilteringIterator struct {
	filteredInterest  string
	currentPosition   int
	backingCollection *CustomerDBCollection
}

func (i *InterestFilteringIterator) First() *Customer {
	i.currentPosition = -1
	return i.Next()
}

func (i *InterestFilteringIterator) Next() *Customer {
	i.currentPosition = i.currentPosition + 1
	for newIdx, customer := range i.backingCollection.customers[i.currentPosition:] {
		if customer.HasInterest(i.filteredInterest) {
			i.currentPosition = newIdx + i.currentPosition
			return &customer
		}
	}
	return nil
}

func (i *InterestFilteringIterator) IsDone() bool {
	return i.currentPosition == len(i.backingCollection.customers)
}

func (i *InterestFilteringIterator) CurrentItem() *Customer {
	return &i.backingCollection.customers[i.currentPosition]
}

type CustomerCollection interface {
	CreateCloudInterestedCustomerIterator() CustomerIterator
}

type CustomerDBCollection struct {
	customers []Customer
}

func (cc *CustomerDBCollection) CreateCloudInterestedCustomerIterator() CustomerIterator {
	return &InterestFilteringIterator{
		currentPosition:   -1,
		filteredInterest:  "Cloud",
		backingCollection: cc}
}

func (cc *CustomerDBCollection) AddCustomer(c Customer) {
	cc.customers = append(cc.customers, c)
}

func (cc *CustomerDBCollection) Get(idx int) Customer {
	return cc.customers[idx]
}

func (cc *CustomerDBCollection) Size() int {
	return len(cc.customers)
}
