// 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

import (
	"fmt"
	"io"
	"os"
	"sync"
)

// Handler is the type for entities that process log streams.
// It will be invoked once per log record in the stream.
type Handler func(r Record)

// Closer is returned from handler constructors that must also be closed.
type Closer func()

// GetHandler gets the active Handler for this context.
func GetHandler(ctx Context) Handler {
	return ctx.Value(handlerKey).(Handler)
}

// Handler returns a new Builder with the given Handler set on it.
func (ctx logContext) Handler(h Handler) Context {
	return ctx.setValue(handlerKey, h)
}

// Stdout returns a Handler that writes to os.Stdout.
// This is conceptually the same as Writer(style, os.Stdout) except the writer is not bound, so if os.Stdout changes
// the new value will be picked up.
func Stdout(style Style) Handler {
	return func(r Record) {
		style(os.Stdout, r)
		fmt.Fprintln(os.Stdout)
	}
}

// Stderr returns a Handler that writes to os.Stderr.
// This is conceptually the same as Writer(style, os.Stderr) except the writer is not bound, so if os.Stderr changes
// the new value will be picked up.
func Stderr(style Style) Handler {
	return func(r Record) {
		style(os.Stderr, r)
		fmt.Fprintln(os.Stderr)
	}
}

// Std returns a Handler that splits writes between to Stderr and Stdout.
func Std(style Style) Handler {
	stderr := Stderr(style)
	stdout := Stdout(style)
	return func(r Record) {
		switch {
		case r.Severity <= ErrorLevel:
			stderr(r)
		default:
			stdout(r)
		}
	}
}

// Writer is a Handler that uses the active Style to write records to an underlying io.Writer
func Writer(style Style, to io.Writer) Handler {
	return func(r Record) {
		style(to, r)
		fmt.Fprintln(to)
	}
}

// Channel is a Handler that passes log records to another Handler through a blocking chan.
// This makes this Handler safe to use from multiple threads
func Channel(to Handler) (Handler, Closer) {
	c := make(chan Record)
	done := make(chan struct{})
	go func() {
		for r := range c {
			to(r)
		}
		close(done)
	}()
	handler := func(r Record) {
		c <- r
	}
	once := sync.Once{}
	closer := func() {
		once.Do(func() {
			close(c)
			<-done
		})
	}
	return handler, closer
}

// Fork forwards all messages to all supplied handlers.
func Fork(handlers ...Handler) Handler {
	return func(r Record) {
		for _, handler := range handlers {
			handler(r)
		}
	}
}

// LimitSplit splits incoming log messages based on their priority.
// It forwards all messages of limit or higher severity to the high handler, and the rest to the low Handler.
func LimitSplit(limit Severity, high Handler, low Handler) Handler {
	return func(r Record) {
		handler := low
		if r.Severity <= limit {
			handler = high
		}
		if handler != nil {
			handler(r)
		}
	}
}
