package Base::Session::Cookie;
# -------------------------------------------------------------------------
# Base::Session::Cookie
#
# - Base::Session::xxx に Cookie インタフェースを与える
#
#
# -------------------------------------------------------------------------
use strict;
use vars qw(@ISA);
@ISA = qw(Base::Session);
use Base::Session;

use Carp;
use CGI::Cookie;
use POSIX qw(strftime);

# -------------------------------------------------------------------------
# new
# - STORE で設定された Base::Sesstion::xxxx を継承
#
# -------------------------------------------------------------------------
sub new {
	my $class = shift;
	my (%option) = @_;

	my $self  = bless {%option}, $class;
	my $store = "Base::Session::$self->{STORE}";
	eval "require $store" || croak $@;
	push(@ISA, $store);

	return $self;
}

# -------------------------------------------------------------------------
# セッションの新規作成
# - クッキーにデータセッションID、ダイジェストを保存する
#
# -------------------------------------------------------------------------
sub create {
	my $class = shift;

	my $self = (ref $class eq "")? $class->new() : $class;

	#
	# セッションデータの作成
	#
	$self->SUPER::create();


	#
	# Cookieの作成
	#
	$self->set_cookie();

	return $self;
}

# -------------------------------------------------------------------------
# セッションの読み込み 
# - セッションIDはクッキーから取得
# - ダイジェストの確認も行う
#
# -------------------------------------------------------------------------
sub open {
	my $class = shift;

	my $self = (ref $class eq "")? $class->new() : $class;

	#
	# クッキーからセッションID、、ダイジェストを取得
	#
	my %cookie = CGI::Cookie->fetch;
	my $cookie_key = $self->{COOKIE_KEY};
	exists $cookie{$cookie_key} or croak "Cookie not found: $cookie_key";

	my %cookie_data = $cookie{$cookie_key}->value;
	my $sid    = $cookie_data{sid};
	my $digest = $cookie_data{digest};


	#
	# セッションデータの読み込み
	#
	$self->SUPER::open($sid);


	#
	# ダイジェストの比較
	#
	$self->is_digest($digest) or croak "digest check failed: $digest";


	#
	# Cookieの有効期限の延長
	#
	$self->set_cookie();

	return $self;
}

# -------------------------------------------------------------------------
# クッキーに保存
# - クッキーにセッションIDとダイジェストを保存
#
# -------------------------------------------------------------------------
sub set_cookie {
	my $self = shift;

	#
	# クッキーの有効期限の設定 変形 RFC1123
	# http://home.netscape.com/newsref/std/cookie_spec.html
	#
	my $expire_time = $self->get('_expire');
	my $expire = strftime "%a, %d-%b-%Y %H:%M:%S GMT", gmtime($expire_time);

	#
	# クッキーにセッションID、ダイジェストを保存
	#
	my $cookie = CGI::Cookie->new(
		-name  => $self->{COOKIE_KEY},
		-value => {
			sid    => $self->id,
			digest => $self->digest,
		},
		($self->{EXPIRE} > 0)? (-expires => $expire) : "",
	);

	print "Set-Cookie: $cookie\n";
}

1;
