func (f AgeFilter) String() string {
	return fmt.Sprintf("AgeFilter(%s)", f.age)
}
String returns a string representation of the filter
package settings
import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"time"
	"poule/gh"
	"poule/operations"
	"github.com/Sirupsen/logrus"
	"github.com/google/go-github/github"
	"github.com/pkg/errors"
	"github.com/urfave/cli"
)
const filterFlagName = "filter"
var FilteringFlag = cli.StringSliceFlag{
	Name:  filterFlagName,
	Usage: "filter based on item attributes",
}
func ParseCliFilters(c *cli.Context) ([]*Filter, error) {
	value, err := NewMultiValuedKeysFromSlice(c.StringSlice(filterFlagName))
	if err != nil {
		return nil, err
	}
	return ParseConfigurationFilters(value.ToSerializedFormat())
}
func ParseConfigurationFilters(values map[string]interface{}) (Filters, error) {
	filters := Filters{}
	for filterType, rawValue := range values {
		value, err := filterValue(rawValue)
		if err != nil {
			return []*Filter{}, err
		}
		filter, err := MakeFilter(filterType, value)
		if err != nil {
			return []*Filter{}, err
		}
		filters = append(filters, filter)
	}
	return filters, nil
}
type Filters []*Filter
func (f Filters) Apply(context operations.Context, item gh.Item) bool {
	for _, filter := range f {
		if !filter.Apply(context, item) {
			return false
		}
	}
	return true
}
type Filter struct {
	Strategy fmt.Stringer
}
func (f *Filter) Apply(context operations.Context, item gh.Item) bool {
	switch {
	case item.IsIssue():
		if f, ok := f.Strategy.(issueFilter); ok {
			return f.ApplyIssue(context, item.Issue)
		}
	case item.IsPullRequest():
		if f, ok := f.Strategy.(pullRequestFilter); ok {
			return f.ApplyPullRequest(context, item.PullRequest)
		}
	default:
		panic("unreachable")
	}
	return true
}
type issueFilter interface {
	ApplyIssue(operations.Context, *github.Issue) bool
	String() string
}
type pullRequestFilter interface {
	ApplyPullRequest(operations.Context, *github.PullRequest) bool
	String() string
}
func MakeFilter(filterType, value string) (*Filter, error) {
	typeMapping := map[string]func(string) (*Filter, error){
		"age":      makeAgeFilter,
		"assigned": makeAssignedFilter,
		"comments": makeCommentsFilter,
		"is":       makeIsFilter,
		"labels":   makeWithLabelsFilter,
		"~labels":  makeWithoutLabelsFilter,
		"contains": makeContainsFilter,
	}
	if constructor, ok := typeMapping[filterType]; ok {
		return constructor(value)
	}
	return nil, errors.Errorf("unknown filter type %q", filterType)
}
type ContainsFilter struct {
	regexp *regexp.Regexp
}
func makeContainsFilter(value string) (*Filter, error) {
	regex, err := regexp.Compile(value)
	if err != nil {
		return nil, err
	}
	return asFilter(ContainsFilter{regexp: regex}), nil
}
func (f ContainsFilter) filter(context operations.Context, issueNum int) bool {
	comments, _, err := context.Client.Issues().ListComments(context.Username, context.Repository, issueNum, nil)
	if err != nil {
		logrus.Error(err)
		return false
	}
	for _, comment := range comments {
		body := strings.Replace(*comment.Body, "\r", "", -1)
		if f.regexp.MatchString(body) {
			return true
		}
	}
	return false
}
func (f ContainsFilter) ApplyIssue(context operations.Context, issue *github.Issue) bool {
	return f.filter(context, *(issue.Number))
}
func (f ContainsFilter) ApplyPullRequest(context operations.Context, pullRequest *github.PullRequest) bool {
	return f.filter(context, *(pullRequest.Number))
}
func (f ContainsFilter) String() string {
	return fmt.Sprintf("ContainsFilter(%s)", f.regexp)
}
type AgeFilter struct {
	age ExtDuration
}
func makeAgeFilter(value string) (*Filter, error) {
	d, err := ParseExtDuration(value)
	if err != nil {
		return nil, errors.Errorf("invalid value %q for \"age\" filter", value)
	}
	return asFilter(AgeFilter{d}), nil
}
func (f AgeFilter) ApplyIssue(context operations.Context, issue *github.Issue) bool {
	return time.Since(*issue.CreatedAt) > f.age.Duration()
}
func (f AgeFilter) ApplyPullRequest(context operations.Context, pullRequest *github.PullRequest) bool {
	return time.Since(*pullRequest.CreatedAt) > f.age.Duration()
}