// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package syslog provides a simple interface to the system log service. It
// can send messages to the syslog daemon using UNIX domain sockets, UDP, or
// TCP connections.
package syslog

import (
	"errors"
	"fmt"
	"log"
	"net"
	"os"
)

type Priority int

const (
	// From /usr/include/sys/syslog.h.
	// These are the same on Linux, BSD, and OS X.
	LOG_EMERG Priority = iota
	LOG_ALERT
	LOG_CRIT
	LOG_ERR
	LOG_WARNING
	LOG_NOTICE
	LOG_INFO
	LOG_DEBUG
)

// A Writer is a connection to a syslog server.
type Writer struct {
	priority Priority
	prefix   string
	conn     serverConn
}

type serverConn interface {
	writeBytes(p Priority, prefix string, b []byte) (int, error)
	writeString(p Priority, prefix string, s string) (int, error)
	close() error
}

type netConn struct {
	conn net.Conn
}

// New establishes a new connection to the system log daemon.
// Each write to the returned writer sends a log message with
// the given priority and prefix.
func New(priority Priority, prefix string) (w *Writer, err error) {
	return Dial("", "", priority, prefix)
}

// Dial establishes a connection to a log daemon by connecting
// to address raddr on the network net.
// Each write to the returned writer sends a log message with
// the given priority and prefix.
func Dial(network, raddr string, priority Priority, prefix string) (w *Writer, err error) {
	if prefix == "" {
		prefix = os.Args[0]
	}
	var conn serverConn
	if network == "" {
		conn, err = unixSyslog()
	} else {
		var c net.Conn
		c, err = net.Dial(network, raddr)
		conn = netConn{c}
	}
	return &Writer{priority, prefix, conn}, err
}

// Write sends a log message to the syslog daemon.
func (w *Writer) Write(b []byte) (int, error) {
	if w.priority > LOG_DEBUG || w.priority < LOG_EMERG {
		return 0, errors.New("log/syslog: invalid priority")
	}
	return w.conn.writeBytes(w.priority, w.prefix, b)
}

func (w *Writer) writeString(p Priority, s string) (int, error) {
	return w.conn.writeString(p, w.prefix, s)
}

func (w *Writer) Close() error { return w.conn.close() }

// Emerg logs a message using the LOG_EMERG priority.
func (w *Writer) Emerg(m string) (err error) {
	_, err = w.writeString(LOG_EMERG, m)
	return err
}
// Crit logs a message using the LOG_CRIT priority.
func (w *Writer) Crit(m string) (err error) {
	_, err = w.writeString(LOG_CRIT, m)
	return err
}
// ERR logs a message using the LOG_ERR priority.
func (w *Writer) Err(m string) (err error) {
	_, err = w.writeString(LOG_ERR, m)
	return err
}

// Warning logs a message using the LOG_WARNING priority.
func (w *Writer) Warning(m string) (err error) {
	_, err = w.writeString(LOG_WARNING, m)
	return err
}

// Notice logs a message using the LOG_NOTICE priority.
func (w *Writer) Notice(m string) (err error) {
	_, err = w.writeString(LOG_NOTICE, m)
	return err
}
// Info logs a message using the LOG_INFO priority.
func (w *Writer) Info(m string) (err error) {
	_, err = w.writeString(LOG_INFO, m)
	return err
}
// Debug logs a message using the LOG_DEBUG priority.
func (w *Writer) Debug(m string) (err error) {
	_, err = w.writeString(LOG_DEBUG, m)
	return err
}

func (n netConn) writeBytes(p Priority, prefix string, b []byte) (int, error) {
	return fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, b)
}

func (n netConn) writeString(p Priority, prefix string, s string) (int, error) {
	return fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, s)
}

func (n netConn) close() error {
	return n.conn.Close()
}

// NewLogger provides an object that implements the full log.Logger interface,
// but sends messages to Syslog instead; flag is passed as is to Logger;
// priority will be used for all messages sent using this interface.
// All messages are logged with priority p.
func NewLogger(p Priority, flag int) *log.Logger {
	s, err := New(p, "")
	if err != nil {
		return nil
	}
	return log.New(s, "", flag)
}
