package queue;

sub main'queue {
    local($nll, @rest) = @_;
    print("*****Queue($nll @rest)\n") if $main'debug;

    @LocalLinks = @rest[0..$nll];
    @Ancestors = @rest[$nll+1..$#rest-1];
    local($url) = $rest[$#rest];

    for $lurl (@LocalLinks){
	$lurl = &url'ConstructURL($url, $lurl);
#	print("Hmmm... $lurl (on page $url)\n") if $main'debug;
	print("\t") if $main'debug;
	if(&main'should($lurl, @Ancestors, $url)){
	    push(@URLQueueA, $lurl);
#	    print("Added $lurl to memory queue\n") if $main'debug;
	    $URLAncestors{$lurl} = join(" ", @Ancestors, $url);
#	    print("Set $lurl 's ancestors to $URLAncestors{$lurl}\n") if $main'debug;
	    &cleanup;
	}
    }
    ### I should return something.  What?
}

sub main'dequeue {
    local($url, @Ancestors);
    print("*****Dequeue\n") if $main'debug;
    &cleanup;
    $url = shift(@URLQueueD);
    @Ancestors = split(' ', $URLAncestors{$url});

    if($url eq ""){
	&write_to_queue(@URLQueueA);
	@URLQueueA = ();
	@chunk = &get_chunk_from_queue;
	push(@URLQueueD, @chunk) if ($#chunk != -1);
	$url = shift(@URLQueueD);
	@Ancestors = split(' ', $URLAncestors{$url});
    }
    if($url){
	($url, @Ancestors);
    }
    else{ return 0; }
}

sub cleanup {
#    print("Cleanup! (to add: $#URLQueueA) (to get: $#URLQueueD)\n") if $main'debug;

    if($#URLQueueA > 100){
	&write_to_queue(@URLQueueA);
	@URLQueueA = ();
    }
    if($#URLQueueD < 2){
	push(@URLQueueD, @mychunk = &get_chunk_from_queue);
    }
}

sub on_queue {
    local($checkme) = @_;
    local($on) = 0;

    if(grep($_ eq $checkme, @URLQueueA)){
	$on = 1;
    }
    elsif(grep($_ eq $checkme, @URLQueueD)){
	$on = 1;
    }
    elsif(&mygrep($checkme, $DiskQueue)){
	$on = 1;
    }

    $on;
}

sub mygrep {
    local($url, $DiskQueue) = @_;

    open(DQ, $DiskQueue);
    while(<DQ>){
	split;
	(return 1 && close(DQ)) if($url eq $_[0]);
    }
    close(DQ);
    0;
}

sub init {
    mkdir("/usr/tmp/$ARGV[1]", 0777);
    $DiskQueue = "/usr/tmp/$ARGV[1]/dq";
    $TmpQueue  = "/usr/tmp/$ARGV[1]/tmpq";
    `touch $DiskQueue`;
}

sub wrapup {
    unlink($TmpQueue);
    open(TMP, ">$TmpQueue");
    for $i (@URLQueueD){
	print(TMP "$i ", $URLAncestors{$i}, "\n");
    }
    open(DQ, $DiskQueue);
    while(<DQ>){
	print TMP $_;
    }
    close(TMP);
    unlink($DiskQueue);
    rename($TmpQueue,$DiskQueue);
    &write_to_queue(@URLQueueA);
    print("|||||||||||||||||||||||||||||||\nDone\n");
    exit(0);
}

sub write_to_queue {
    local(@writeme) = @_;

    open(DQ, ">>$DiskQueue") || die "Can't write to disk queue: $DiskQueue";
    select(DQ); $| = 1; select(STDOUT);
    for $qitem (@writeme){
	print("Writing $qitem to disk\n") if $main'debug;
	print(DQ $qitem, " ", $URLAncestors{$qitem}, "\n") unless ($qitem eq "");
    }
    close(DQ);
}

sub get_chunk_from_queue {
    local(@returnlist);

    open(DQ, $DiskQueue) || warn "Hey, no dq \"$DiskQueue\", with $#URLQueueD in memory!";
    for $n (1..12){
	chop($qitemlist = <DQ>);
	($qitem, @qitem_ancestors) = split(' ', $qitemlist);
	next if $qitem eq "";
	push(@returnlist, $qitem) unless (!$qitem);
	print("Got $qitem off of disk queue\n") if ($main'debug && !($qitem eq ""));
	$URLAncestors{$qitem} = join(' ', @qitem_ancestors);
	print("Loaded $qitem 's ancestors as $URLAncestors{$qitem}\n") if $main'debug;
    }
    unlink($TmpQueue);
    open(TMP, ">>$TmpQueue") || warn "uh oh, no temp queue";
    while(<DQ>){
	print(TMP $_) unless ($_ eq "");
    }
    close(TMP);
#    print("I have @returnlist to add.  Kill dq...?\n");
#    $in = (<STDIN>);
#    print "DQ: ".`ls -l $DiskQueue`;
    unlink($DiskQueue);
#    print("I just removed the DiskQueue.  Am now moving the tmpqueue to it\n");
#    print "TQ: ".`ls -l $TmpQueue`;
    rename($TmpQueue, $DiskQueue);

    @returnlist;
}


1;
