#!/usr/bin/perl
#
# $Id: ScanSet.pm,v 1.7 2000/05/03 22:49:31 levine Exp $
#
# Copyright (C) 2000  James D. Levine (jdl@vinecorp.com)
#
#
#   This program is free software; you can redistribute it and/or
#   modify it under the terms of the GNU General Public License
#   as published by the Free Software Foundation; either version 2
#   of the License, or (at your option) any later version.
# 
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
# 
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
#   02111-1307, USA.
#
####################################################################

use strict;

use PortScan::ScannedHost;

package PortScan::ScanSet;

sub new
{
    my ($type, $tag, $hosts, $properties, $ports) = @_;

    $hosts = {} if !defined $hosts;
    $properties = {} if !defined $properties;
    $ports = {} if !defined $ports;

    my $self = 
    {
	tag => $tag,
	properties => $properties, # app-specific meta-tags k -> v (v is a string)
	hosts => $hosts,
	all_scanned_ports => $ports, # dummy PortSpecs for all ports scanned
    };

    bless $self, $type;

    return $self;
}

sub hash_to_text
  {
    my $h = shift;
    my $t;
    while (my ($k, $v) = each %$h)
      {
	$t .= "`${k}' -> `${v}'\n";
      }
    $t;
  }

sub to_text
  {
    my $self = shift;

    return
      "tag: " . $self->{tag} . "\n" 
    . "properties:\n" 
    . hash_to_text($self->{properties}) 
    . "hosts:\n"  
    . hash_to_text($self->{hosts})
      ;
  }

sub set_or_get
{
    my $field = shift;
    my $self = shift;
    my $val = shift;

    $self->{$field} = $val if defined $val;

    return $self->{$field};
}

sub tag
{
    return set_or_get('tag', @_);
}

sub clone_deep
{
    my ($self, $from, $when, $tag1, $tag2) = @_;

    my $hosts = {};
    my $properties = {};

    my ($k, $v);
    my $h = $self->hosts();

    while ( ($k, $v) = each %$h )
    {
	$hosts->{$k} = $v->clone();
    }

    my $p = $self->{properties};
    while ( ($k, $v) = each %$p)
    {
	$properties->{$k} = $v;
    }

    return new ScanSet($from, $when, $tag1, $tag2, $hosts, $properties);
}

sub set_property
{
    my ($self, $k, $v) = @_;
    $self->{properties}->{$k} = $v;
}

sub get_property
{
    my ($self, $k) = @_;
    $self->{$k};
}

sub hosts { return set_or_get('hosts', @_); }
sub properties { return set_or_get('properties', @_); }
sub all_scanned_ports { return set_or_get('all_scanned_ports', @_); }

sub add_scanned_port 
{
    my ($self, $spec) = @_;

    $self->all_scanned_ports()->{$spec->key_for()} = $spec;
}

sub hosts_sorted_list
{
    my $self = shift;
    return PortScan::ScannedHost::sorted_list values %{$self->hosts()};
}

sub add_host
{
    my ($self, $scanned_host) = @_;
    $self->hosts()->{$scanned_host->addr()} = $scanned_host;
    $scanned_host->scan_set($self);
}

sub remove_host
{
    my ($self, $addr) = @_;
    delete $self->hosts()->{$addr};
}


sub get_host
{
    my ($self, $addr) = @_;
    $self->hosts()->{$addr};
}

1;

