/*=====================================================================*/
/*    serrano/prgm/project/bigloo/runtime/Jlib/client_socket.java      */
/*    -------------------------------------------------------------    */
/*    Author      :  Manuel Serrano                                    */
/*    Creation    :  Tue Dec  5 10:53:03 2000                          */
/*    Last change :  Sat Jul 14 06:49:33 2001 (serrano)                */
/*    Copyright   :  2000-01 Manuel Serrano                            */
/*    -------------------------------------------------------------    */
/*    The Client Socket implementation for the JVM back-end.           */
/*=====================================================================*/
using System;
using System.Net;
using System.Net.Sockets;

namespace bigloo
{
  /*---------------------------------------------------------------------*/
  /*    SOCKET ...                                                       */
  /*---------------------------------------------------------------------*/
  public sealed class client_socket: socket
  {
    /*--- private fields ---------------------------------------------------*/
    private readonly Socket _socket;
    private readonly bool blocking;
 
    /*--- constructors ----------------------------------------------------*/
    // This is a client socket creation
    public client_socket( byte[]  hostname,
                          int     port,
                          bool    blocking )
      : base()
    {
      this.blocking= blocking;

      try
      {
        IPHostEntry     ip_host_entry= Dns.Resolve( foreign.newstring( hostname ) );
        IPEndPoint      ip_end_point= new IPEndPoint( ip_host_entry.AddressList[0], port );

        _socket= new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        _socket.Connect( ip_end_point );
        set_socket_io_ports( _socket, blocking );
      }
      catch (Exception  e)
      {
        socket_error( "make-client-socket",
                      "cannot create socket (" + e.Message + ")",
                      hostname );
      }
    }

    internal client_socket( Socket  _socket,
                            bool    blocking )
      : base()
    {
      this._socket= _socket;
      this.blocking= blocking;
      set_socket_io_ports( _socket, blocking );
    }

    /*--- public methods --------------------------------------------------*/
    public override Object HOSTNAME()
    {
      return foreign.getbytes( Dns.GetHostByAddress( ((IPEndPoint)_socket.RemoteEndPoint).Address ).HostName );
    }

    public override Object HOSTIP()
    {
      return foreign.getbytes( ((IPEndPoint)_socket.RemoteEndPoint).Address.ToString() );
    }

    public override byte[] local_addr()
    {
      return foreign.getbytes( ((IPEndPoint)_socket.LocalEndPoint).Address.ToString() );
    }

    public override socket socket_dup()
    {
      return new client_socket( _socket, blocking );
    }

    public override Object shutdown( bool  close_socket )
    {
      close();
      // !!!!! On appelle _socket.Shutdown() ou bien ?????  (Pas fait en Java)
      down= true;
      return bigloo.foreign.BUNSPEC;
    }

    public override Object close()
    {
      _socket.Close();
      return base.close();
    }

    public override int PORT()
    {
      return ((IPEndPoint)_socket.RemoteEndPoint).Port;
    }

    public override void write( output_port  p )
    {
      p.write( "#<socket:" + foreign.newstring( HOSTNAME() ) + "." + PORT() + ">" );
    }
  }
}
