package Sidef::Types::Glob::SocketHandle;

use utf8;
use 5.016;

use parent qw(
  Sidef::Types::Glob::FileHandle
);

sub new {
    my (undef, $sh, $socket) = @_;

    bless {
           fh     => $sh,
           parent => $socket,
          },
      __PACKAGE__;
}

*call = \&new;

sub setsockopt {
    my ($self, $level, $optname, $optval) = @_;
    (CORE::setsockopt($self->{fh}, $level, "$optname", $optval))
      ? (Sidef::Types::Bool::Bool::TRUE)
      : (Sidef::Types::Bool::Bool::FALSE);
}

sub getsockopt {
    my ($self, $level, $optname) = @_;
    Sidef::Types::String::String->new(CORE::getsockopt($self->{fh}, $level, "$optname") // return undef);
}

sub getpeername {
    my ($self) = @_;
    Sidef::Types::String::String->new(CORE::getpeername($self->{fh}) // return undef);
}

sub getsockname {
    my ($self) = @_;
    Sidef::Types::String::String->new(CORE::getsockname($self->{fh}));
}

sub bind {
    my ($self, $name) = @_;
    CORE::bind($self->{fh}, "$name")
      ? (Sidef::Types::Bool::Bool::TRUE)
      : (Sidef::Types::Bool::Bool::FALSE);
}

sub listen {
    my ($self, $queuesize) = @_;

    CORE::listen($self->{fh}, $queuesize)
      ? (Sidef::Types::Bool::Bool::TRUE)
      : (Sidef::Types::Bool::Bool::FALSE);
}

sub accept {
    my ($self) = @_;
    CORE::accept(my $sh, $self->{fh}) || return undef;
    Sidef::Types::Glob::SocketHandle->new($sh);
}

sub connect {
    my ($self, $name) = @_;
    CORE::connect($self->{fh}, "$name")
      ? (Sidef::Types::Bool::Bool::TRUE)
      : (Sidef::Types::Bool::Bool::FALSE);
}

sub recv {
    my ($self, $length, $flags) = @_;
    my $content = "";
    CORE::recv($self->{fh}, $content, CORE::int($length), CORE::int($flags)) // return undef;
    Sidef::Types::String::String->new($content);
}

sub send {
    my ($self, $msg, $flags, $to) = @_;
    CORE::send($self->{fh}, "$msg", CORE::int($flags), defined($to) ? $to->get_value : ())
      ? (Sidef::Types::Bool::Bool::TRUE)
      : (Sidef::Types::Bool::Bool::FALSE);
}

sub shutdown {
    my ($self, $how) = @_;
    CORE::shutdown($self->{fh}, $how)
      ? (Sidef::Types::Bool::Bool::TRUE)
      : (Sidef::Types::Bool::Bool::FALSE);
}

1
