# -*- mode: perl; coding: utf-8 -*-
# Keitairc::Log
#
# Copyright (c) 2008 Jun Morimoto <morimoto@mrmt.net>
# Copyright (c) 2010 ISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
# This program is covered by the GNU General Public License 2

package Keitairc::Log;
use Keitairc::Config;
use POSIX qw(strftime locale_h);
use strict;
use warnings;

sub new {
	my ($proto, $arg) = @_;
	my $me = {};

	bless $me;

	if (defined $arg->{config}) {
		$me->config($arg->{config});
	} else {
		require Keitairc::Log::Stdio;
		$me->{writer} = new Keitairc::Log::Stdio();
	}

	return $me;
}

sub config {
	my ($me, $cf) = @_;
	$me->{Config} = $cf;
	($me->{type}, undef) = split(':', $me->{Config}->log(), 2);

	my $fallback = 0;
	if ($me->{type} =~ /^syslog$/i) {
		if (eval "use Sys::Syslog") {
			require Keitairc::Log::Syslog;
			$me->{writer} = new Keitairc::Log::Syslog({config => $me->{Config}});
		} else {
			# force fallback to file writer
			$me->{type} = 'file';
			$fallback = 1;
		}
	}

	if ($me->{type} =~ /^file$/i ) {
		require Keitairc::Log::File;
		$me->{writer} = new Keitairc::Log::File({config => $me->{Config}});
	} else {
		require Keitairc::Log::Stdio;
		$me->{writer} = new Keitairc::Log::Stdio({config => $me->{Config}}) if (!defined $me->{writer} || !$me->{writer});
	}
	if ($fallback) {
		$me->log_error('Sys::Syslog is missing, fallback to file log writer');
	}
}

sub log_access {
	my ($me, $ip, $request, $response) = @_;
	my $old_locate = setlocale(LC_TIME);
	setlocale(LC_TIME, 'POSIX');
	$me->{writer}->log_access(sprintf('%s %s %s [%s] "%s" %s %s "%s" "%s"',
					  $ip || '-',
					  '-',
					  $request->header('Remote-User') || '-',
					  strftime('%d/%b/%Y:%T %z', localtime()),
					  $request->method() . ' ' . $request->uri() || '-',
					  $response->code,
					  length($response->content),
					  $request->header('referer') || '-',
					  $request->header('User-Agent') || '-'));
	setlocale(LC_TIME, $old_locate);
}

sub _format {
	my ($me, $m) = @_;
	if (!defined $me->{type} || $me->{type} !~ /^syslog$/i) {
		my $old_locate = setlocale(LC_TIME);
		setlocale(LC_TIME, 'POSIX');
		$m = strftime('%b %d %T ', localtime()) . $m;
		setlocale(LC_TIME, $old_locate);
	}
	return $m;
}

sub log {
	my ($me, $m) = @_;
	$me->{writer}->log_info($me->_format($m));
}

sub log_error {
	my ($me, $m) = @_;
	$me->{writer}->log_error($me->_format($m));
}

sub log_debug {
	my ($me, $m) = @_;
	$me->{writer}->log_debug($me->_format($m));
}

sub log_die {
	my ($me, $m) = @_;
	$me->log_error($m);
	die;
}

1;
