package Firewall::Config::Element::ServiceGroup::Role;

#------------------------------------------------------------------------------
# 加载扩展模块
#------------------------------------------------------------------------------
use Moose::Role;

#------------------------------------------------------------------------------
# 引入 Firewall::Config::Element::ServiceGroup::Role 角色
#------------------------------------------------------------------------------
with 'Firewall::Config::Element::Role';

#------------------------------------------------------------------------------
# Firewall::Config::Element::ServiceGroup::Role 通用属性
#------------------------------------------------------------------------------
has srvGroupName => (is => 'ro', isa => 'Str', required => 1,);

has srvGroupMembers => (
  is      => 'ro',
  does    => 'HashRef[ Firewall::Config::Element::Service::Role | Firewall::Config::Element::ServiceGroup::Role | Undef ]',
  default => sub { {} },
);

has dstPortRangeMap => (is => 'ro', isa => 'HashRef[Firewall::Utils::Set]', default => sub { {} },);

has refnum => (is => 'ro', isa => 'Int', default => 0);

has range => (is => 'ro', isa => 'Firewall::Utils::Set', lazy => 1, builder => '_buildRange',);

#------------------------------------------------------------------------------
# addSrvGroupMember 添加服务端口组成员
#------------------------------------------------------------------------------
sub addSrvGroupMember {
  my ($self, $srvGroupMemberName, $obj) = @_;
  confess "ERROR: srvGroupMemberName must defined" if not defined $srvGroupMemberName;
  unless (not defined $obj
    or $obj->does('Firewall::Config::Element::Service::Role')
    or $obj->does('Firewall::Config::Element::ServiceGroup::Role'))
  {
    confess
      "ERROR: 参数 obj 只能是 Firewall::Config::Element::Service::Role or Firewall::Config::Element::ServiceGroup::Role or Undef";
  }
  $self->{srvGroupMembers}{$srvGroupMemberName} = $obj;
  if (defined $obj) {
    for my $protocol (keys %{$obj->dstPortRangeMap}) {
      if (not defined $self->dstPortRangeMap->{$protocol}) {
        $self->dstPortRangeMap->{$protocol} = Firewall::Utils::Set->new;
      }
      $self->dstPortRangeMap->{$protocol}->mergeToSet($obj->dstPortRangeMap->{$protocol});
    }
  }
} ## end sub addSrvGroupMember

#------------------------------------------------------------------------------
# 重写 Firewall::Config::Element::Role => _buildRange 方法
#------------------------------------------------------------------------------
sub _buildRange {
  my $self  = shift;
  my $range = Firewall::Utils::Set->new;
  for my $service (values %{$self->srvGroupMembers}) {
    $range->mergeToSet($service->range);
  }
  return $range;
}

1;
