// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package log

// Filter is used by the log system to drop log records that don't match the filter.
// It is invoked for each property attached to the log context.
// It should return true if the context passes the filter.
type Filter func(ctx Context, key string, value interface{}) bool

// PreFilter is an optimised version of Filter that is invoked only for the initial setting of the Severity property.
// This is an optimization for the most common binning case.
// It should return true if the severity is active.
type PreFilter func(severity Severity) bool

// GetFilter gets the active Filter for this context.
func GetFilter(ctx Context) Filter {
	return ctx.Value(filterKey).(Filter)
}

// GetPreFilter gets the active PreFilter for this context.
func GetPreFilter(ctx Context) PreFilter {
	return ctx.Value(preFilterKey).(PreFilter)
}

// Filter returns a context with the given Filter set on it.
func (ctx logContext) Filter(f Filter) Context {
	return ctx.setValue(filterKey, f)
}

// PreFilter returns a context with the given PreFilter set on it.
func (ctx logContext) PreFilter(f PreFilter) Context {
	return ctx.setValue(preFilterKey, f)
}

// Pass is an implementation of Filter that does no filtering.
func Pass(ctx Context, key string, value interface{}) bool { return true }

// Null is an implementation of PreFilter that drops all log messages.
func Null(limit Severity) bool { return false }

// Limit returns an implementation of PreFilter that allows only log messages of equal or higher priority to the
// specified limit.
func Limit(limit Severity) PreFilter {
	return func(severity Severity) bool {
		return severity <= limit
	}
}

// NoLimit is an implementation of PreFilter that allows all messages through.
func NoLimit(Severity) bool { return true }
