package ledger

import (
	"regexp"
)

type Like func(Delta) bool

type Likes []Like

func LikeWith(pattern string) Like {
	l := LikeName(pattern)
	return func(d Delta) bool {
		if l(d) {
			return true
		}
		for _, d := range d.with {
			if l(d) {
				return true
			}
		}
		return false
	}
}

func LikeTransactions(deltas ...Delta) Like {
	return func(d Delta) bool {
		for i := range deltas {
			if deltas[i].Transaction == d.Transaction {
				return true
			}
		}
		return false
	}
}

func LikeTransaction(delta Delta) Like {
	return LikeTransactions(delta)
}

func LikeBefore(date string) Like {
	return func(d Delta) bool {
		return date >= d.Date
	}
}

func LikeAfter(date string) Like {
	return func(d Delta) bool {
		return date <= d.Date
	}
}

func LikeNotName(pattern string) Like {
	return func(d Delta) bool {
		return !like(pattern, d.Name)
	}
}

func LikeNot(like Like) Like {
	return func(d Delta) bool {
		return !like(d)
	}
}

func NotLikeName(pattern string) Like {
	return LikeNot(LikeName(pattern))
}

func LikeName(pattern string) Like {
	return func(d Delta) bool {
		return like(pattern, d.Name)
	}
}

func like(pattern string, other string) bool {
	return regexp.MustCompile(pattern).MatchString(other)
}

func (likes Likes) Any(delta Delta) bool {
	for i := range likes {
		if likes[i](delta) {
			return true
		}
	}
	return false
}

func (likes Likes) All(delta Delta) bool {
	for i := range likes {
		if !likes[i](delta) {
			return false
		}
	}
	return true
}
