{{/*
Copyright 2019-present Facebook Inc. All rights reserved.
This source code is licensed under the Apache 2.0 license found
in the LICENSE file in the root directory of this source tree.
*/}}

{{/* gotype: entgo.io/ent/entc/gen.Graph */}}

{{ define "privacy/filter" }}

{{ $pkg := base $.Config.Package }}

type (
	// Filter is the interface that wraps the Where function
	// for filtering nodes in queries and mutations.
	Filter interface {
		// Where applies a filter on the executed query/mutation.
		Where(entql.P)
	}

	// The FilterFunc type is an adapter that allows the use of ordinary
	// functions as filters for query and mutation types.
	FilterFunc func(context.Context, Filter) error
)

// EvalQuery calls f(ctx, q) if the query implements the Filter interface, otherwise it is denied.
func (f FilterFunc) EvalQuery(ctx context.Context, q {{ $pkg }}.Query) error {
	fr, err := queryFilter(q)
	if err != nil {
		return err
	}
	return f(ctx, fr)
}

// EvalMutation calls f(ctx, q) if the mutation implements the Filter interface, otherwise it is denied.
func (f FilterFunc) EvalMutation(ctx context.Context, m {{ $pkg }}.Mutation) error {
	fr, err := mutationFilter(m)
	if err != nil {
		return err
	}
	return f(ctx, fr)
}

var _ QueryMutationRule = FilterFunc(nil)

func queryFilter(q {{ $pkg }}.Query) (Filter, error) {
	switch q := q.(type) {
	{{- range $n := $.Nodes }}
		case *{{ $pkg }}.{{ $n.QueryName }}:
			return q.Filter(), nil
	{{- end }}
	default:
		return nil, Denyf("{{ $pkg }}/privacy: unexpected query type %T for query filter", q)
	}
}

func mutationFilter(m {{ $pkg }}.Mutation) (Filter, error) {
	switch m := m.(type) {
	{{- range $n := $.Nodes }}
		case *{{ $pkg }}.{{ $n.MutationName }}:
			return m.Filter(), nil
	{{- end }}
	default:
		return nil, Denyf("{{ $pkg }}/privacy: unexpected mutation type %T for mutation filter", m)
	}
}
{{ end }}


