use strict;
use warnings;

use Test::Fatal;
use Test::More 0.88;

use DateTime;

undef $ENV{PERL_DATETIME_DEFAULT_TZ};

# These tests are for a bug related to a bad interaction between the
# horrid ->_handle_offset_modifier method and calling ->set_time_zone
# on a real Olson time zone.  When _handle_offset_modifier was called
# from set_time_zone, it tried calling ->_offset_for_local_datetime,
# which was bogus, because at that point it doesn't know the local
# date time any more, only UTC.
#
# The fix is to have ->_handle_offset_modifier call ->offset when it
# knows that UTC is valid, which is determined by an arg to
# ->_handle_offset_modifier

# These tests come from one of the zdump-generated test files in
# DT::TZ
{
    my $dt = DateTime->new(
        year      => 1922, month  => 8,  day    => 31,
        hour      => 23,   minute => 59, second => 59,
        time_zone => 'UTC',
    );
    $dt->set_time_zone('Africa/Accra');

    is( $dt->year,  1922, 'local year should be 1922 (1922-08-31 23:59:59)' );
    is( $dt->month, 8,    'local month should be 8 (1922-08-31 23:59:59)' );
    is( $dt->day,   31,   'local day should be 31 (1922-08-31 23:59:59)' );
    is( $dt->hour,  23,   'local hour should be 23 (1922-08-31 23:59:59)' );
    is( $dt->minute, 59,  'local minute should be 59 (1922-08-31 23:59:59)' );
    is( $dt->second, 59,  'local second should be 59 (1922-08-31 23:59:59)' );

    is( $dt->is_dst, 0, 'is_dst should be 0 (1922-08-31 23:59:59)' );
    is( $dt->offset, 0, 'offset should be 0 (1922-08-31 23:59:59)' );
    is(
        $dt->time_zone_short_name, 'GMT',
        'short name should be GMT (1922-08-31 23:59:59)'
    );
}

{
    my $dt = DateTime->new(
        year      => 2013,
        month     => 3,
        day       => 10,
        hour      => 2,
        minute    => 4,
        time_zone => 'floating',
    );

    like(
        exception { $dt->set_time_zone('America/Los_Angeles') },
        qr/\QInvalid local time for date in time zone/,
        'got an exception when trying to set time zone when it leads to invalid local time'
    );

    is(
        $dt->time_zone()->name(),
        'floating',
        'time zone was not changed after set_time_zone() throws an exception'
    );
}

{
    my $dt = DateTime->now( time_zone => 'America/Chicago' );

    ok(
        $dt->set_time_zone('America/Chicago'),
        'set_time_zone returns object when time zone name is same as current'
    );

    ok(
        $dt->set_time_zone( $dt->time_zone() ),
        'set_time_zone returns object when time zone object is same as current'
    );
}

done_testing();
