use Test;

use HTTP::Cookies;
# strangely these aren't required for the test to work
#require HTTP::Request;
#require HTTP::Response;

plan 29;

BEGIN my $file = './cookies.dat';
LEAVE try $file.IO.unlink;

my $c = HTTP::Cookies.new(
    file     => $file,
);

# new
ok $c, 'new 1/3';
is $c.file, $file, 'new 2/3';
is $c.autosave, 0, 'new 3/3';

# set-cookie
$c.set-cookie(
    'Set-Cookie: name1=value1; expires=DATE; Path=/; Domain=gugle.com; Secure; HttpOnly'
);
my $c1 = $c.cookies[0];
ok $c1, 'set-cookie 1/11';
is $c1.name, 'name1', 'set-cookie 2/11';
is $c1.value, 'value1', 'set-cookie 3/11';
is $c1.fields.elems, 0, 'set-cookie 4/11';
is $c1.secure, 'Secure', 'set-cookie 5/11';
is $c1.httponly, 'HttpOnly', 'set-cookie 6/11';

$c.set-cookie(
    'Set-Cookie: name2=value2; expires=DATE2; Path=/path; Domain=gugle.com;'
);
my $c2 = $c.cookies[1];
ok $c2, 'set-cookie 7/11';
is $c2.name, 'name2', 'set-cookie 8/11';
is $c2.value, 'value2', 'set-cookie 9/11';
is $c2.fields.elems, 0, 'set-cookie 10/11';
ok !$c2.secure, 'set-cookie 11/11';

# Str
my $result = "Set-Cookie: name1=value1; expires=DATE; Path=/; Domain=gugle.com; Secure; HttpOnly\nSet-Cookie: name2=value2; expires=DATE2; Path=/path; Domain=gugle.com";

my token set_cookie {
   ^^ Set\-Cookie\:\s+
}

my token name_1 { name1\=value1\;\s+ }
my token expires_1 { :i expires\=DATE }
my token path_1 { :i Path\=\/ }
my token domain_1 { :i Domain\=gugle\.com }
my token secure_1 { Secure }
my token http_only_1 { HttpOnly }
my token fields_1 {
                     [    <expires_1> 
                       |  <path_1>
                       |  <domain_1>
                       |  <secure_1>
                       |  <http_only_1>
                     ] * % '; '

}

my token cookie_1 { 
                     <set_cookie>
                     <name_1>
                     <fields_1>
                     $$
}


my token name_2 { name2\=value2\;\s+ }

my token expires_2 { :i expires\=DATE2 } 
my token path_2 { :i Path\=\/path } 
my token domain_2 { :i Domain\=gugle\.com }

my token fields_2 {
   [  
         <expires_2>
      |  <path_2>
      |  <domain_2>
   ] * % '; '
}


my token cookie_2 { 
                     <set_cookie>
                     <name_2> 
                     <fields_2>
                     $$
}


my rule cookies { 
                   <cookie_1>
                   <cookie_2>
}

like $c.Str, /^<cookies>$/, "Str 1/6";
like $c.Str, /<expires_1>/, "Str 2/6"; 
like $c.Str, /<path_1>/, "Str 3/6";
like $c.Str, /<domain_1>/, "Str 4/6";
like $c.Str, /<secure_1>/, "Str 5/6";
like $c.Str, /<http_only_1>/, "Str 6/6";



# save
my $file_header = "#LWP6-Cookies-0.1\n";
my $elems_before_save = $c.cookies.elems;
$c.save;

my token file_header { ^^ '#'LWP6\-Cookies\-0\.1 $$ }

my rule cookie_file {
   <file_header>
   <cookies>

}

like $c.file.IO.slurp, /<cookie_file>/, 'save 1/1';

# clear
$c.clear;
ok !$c.cookies, 'clear 1/1';

# load
$c.load;

is $c.cookies.elems, $elems_before_save, "Same number of cookies";
#like $c.Str, /^<cookies>$/, "load 1/1";

$c = HTTP::Cookies.new(
    file     => $file,
    autosave => 1,
);
$c.load;

# add-cookie-header
$c.set-cookie(
    'Set-Cookie: namek=songo; expires=DATE2; Domain=gugyl.com;'
);

my $req = HTTP::Request.new(GET => 'http://gugyl.com');
$c.add-cookie-header($req);
# Domain restriction
is $req.field('Cookie').values.elems, 1, 'add-cookie-header 1/?';

$c.set-cookie(
    'Set-Cookie: name3=value3; expires=DATE2; Path=/;'
);
$req = HTTP::Request.new(GET => 'http://gugle.com');
$c.add-cookie-header($req);
# 'Domain'less cookies
#
# TODO:
#is $req.field('Cookie').values.elems, 2, 'add-cookie-header 2/3';

$req = HTTP::Request.new(GET => 'http://gugle.com/path');
$c.add-cookie-header($req);
# Path restriction
#
# TODO:
#is $req.field('Cookie').values.elems, 1, 'add-cookie-header 3/3';

# extract-cookkies
subtest {
diag HTTP::Response.^mro>>.perl;
my $resp = HTTP::Response.new(200);
$resp.field(Set-Cookie => 'k=v');
$c.extract-cookies($resp);
is $c.cookies.elems, 5, 'extract-cookies 1/1';
}, "extract-cookies 1/1";

# clear-expired
$c.set-cookie('Set-Cookie: n1=v1; Expires=Sun, 06 Nov 1994 08:49:37 GMT');
ok $c.clear-expired, 'clear-expired 1/3';
is $c.cookies.elems, 5, 'clear-expired 2/3';
ok ! $c.cookies.grep({ .name eq 'n1' }), 'clear-expired 3/3';

# autosave
$c.clear;
is $c.cookies.elems, 0, 'autosave 1/1';
