#!/usr/bin/perl

use strict;
use warnings;

use Test::More 'no_plan';

use FreeBSD::Ports;
use FreeBSD::Ports::Port;

use IO::File qw(O_RDONLY);

use constant INDEX_FILE => 't/INDEX.sample';
use constant ASCII_FILE => 't/complex_port_as_ascii';


# Tests for FreeBSD::Ports
my $ports_original = tie my(%port_original), 'FreeBSD::Ports', INDEX_FILE;
my $ports = tie my(%port), $ports_original;
{
    # Check we created a ports object correctly
    ok( defined $ports, 'tie() created an object' );
    isa_ok( $ports, 'FreeBSD::Ports', 'in the right class' );

    # We should have 95 ports
    is(scalar keys %port, 95, 'right number of ports');
}

my $ports_clone = tie my(%port_clone), $ports;
{
    # Check we cloned the ports object
    ok( defined $ports_clone, 'object cloned' );
    isa_ok( $ports_clone, 'FreeBSD::Ports', 'cloned in the right class' );

    # Check that tom@FreeBSD.org maintains one port
    $ports_clone->maintainer('tom@Freebsd.org');
    ok( scalar keys %port_clone == 1, 'I maintain 1 port');
    my($unused_name, $port) = each %port_clone;
    # ...and that port is in 2 categories
    my @categ = $port->all_categories();
    is( @categ, 2, 'is in 2 categories' );
    my %categ = %{ $port->all_categories() };
    # ...and that this port is not in the 'www' category
    ok( !exists $categ{'www'}, 'not in the www category' );
    # ...but is in the 'perl5' category
    ok( exists $categ{'perl5'}, 'but is in the perl5 category' );
    # ...and the 'textproc' category
    ok( exists $categ{'textproc'}, 'and is in the textproc category' );
}
# Reset the cloned ports object
undef $ports_clone;
$ports_clone = tie %port_clone, $ports;

{
    # Check the iterators work correctly
    my @keys_a = keys %port_clone;
    my $first_key = each %port_clone;
    my @keys_b = keys %port_clone;
    ok( @keys_a == @keys_b, 'FIRSTKEY resets iterator');
    ok( grep($first_key, @keys_b), 'keys list contains first hash entry' );

    # Check the category() method
    $ports_clone->category('japanese');
    my $count = scalar keys %port_clone;
    is( $count, 4, 'category() method' );
}
# Reset the cloned ports object
undef $ports_clone;
$ports_clone = tie %port_clone, $ports;

{
    # Test case insensitive matching and sort reverse alphabetically
    $ports->sort('rev_alpha');
    $ports->match('gnome', 'COMMENT', 1);
    my @match = keys %port;
    is( @match, 5, 'case insensitive matching' );

    # Check the reverse sorting worked
    my @sorted = reverse sort @match;
    my $identical = 0;
    COMPARE: if (@match == @sorted) {
	for (0 .. @match-1) {
	    last COMPARE if $match[$_] ne $sorted[$_];
	}
	# At this point we have checked all elements in @match
	$identical = 1;
    }
    ok( $identical, 'reverse sorting' );
}

{
    # Check 7 ports contain 'Perl module' in COMMENT
    $ports_clone->match('Perl module');
    is( keys %port_clone, 7, 'test match() method');
    # and that none of these ports match a nonsense word
    $ports_clone->match('lalalalatesttest');
    is( keys %port_clone, 0, 'no ports match a nonsense word');
}


# Tests for FreeBSD::Ports::Port
{
    my $index = IO::File->new(INDEX_FILE, O_RDONLY);
    isa_ok( $index, 'IO::File', 'read INDEX file' );

    # Check some attributes for a port
    my $port = FreeBSD::Ports::Port->new('mysql-client', $index);
    isa_ok( $port, 'FreeBSD::Ports::Port', 'found port' );
    is( $port->name(), 'mysql-client-4.1.0', 'checked name' );
    is( $port->www(), 'http://www.mysql.com/', 'checked WWW' );
    my %depends = %{ $port->build_depends() };
    ok( exists $depends{'libtool-1.3.5_1'}, 'checked dependency' );

    # Check we can find the last port in the INDEX
    my $last_port = FreeBSD::Ports::Port->new('vtwm-5.4.6a', $index);
    isa_ok( $last_port, 'FreeBSD::Ports::Port', 'found last port' );
    # ...and the first port
    my $first_port = FreeBSD::Ports::Port->new('libnova-0.8.0', $index);
    isa_ok( $first_port, 'FreeBSD::Ports::Port', 'found first port' );

    # Test the example long INDEX line (check these modules will work if
    # future fields are added to INDEX)
    my $future_port = FreeBSD::Ports::Port->new('longerline', $index);
    is( $future_port->www(), 'http://www.example.com/', 'correct WWW for long INDEX line' );
    is( $future_port->primary_category(), 'misc', 'correct category for long INDEX line' );
    is( $future_port->maintainer(), 'someone@example.com', 'correct maintainer for long INDEX line' );

    # Check the as_ascii method outputs what we expect with a complex port
    my $complex_port = FreeBSD::Ports::Port->new('gnomekiss-1.6', $index);
    my $ascii_file = IO::File->new( ASCII_FILE, O_RDONLY ) or die $!;
    my $ascii = join( '', $ascii_file->getlines() );
    cmp_ok( $complex_port->as_ascii(), 'eq', $ascii, 'as_ascii' );
}
