/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed under the MIT License (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.blankstyle.vertx.php.net;

import com.blankstyle.vertx.php.Handler;
import com.blankstyle.vertx.php.streams.ExceptionSupport;
import com.blankstyle.vertx.php.streams.ReadStream;
import com.blankstyle.vertx.php.streams.WriteStream;
import com.blankstyle.vertx.php.util.PhpTypes;
import com.caucho.quercus.env.BooleanValue;
import com.caucho.quercus.env.Env;
import com.caucho.quercus.env.NumberValue;
import com.caucho.quercus.env.Value;
import com.caucho.quercus.env.StringValue;

/**
 * A PHP compatible implementation of the Vert.x NetSocket.
 *
 * @author Jordan Halterman
 */
public class NetSocket implements ReadStream<NetSocket>, WriteStream<NetSocket>, ExceptionSupport<NetSocket> {

  private org.vertx.java.core.net.NetSocket socket;

  public NetSocket(org.vertx.java.core.net.NetSocket socket) {
    this.socket = socket;
  }

  /**
   * Returns the local socket address.
   */
  public Value localAddress(Env env) {
    return env.createString(socket.localAddress().toString());
  }

  /**
   * Returns the remote socket address.
   */
  public Value remoteAddress(Env env) {
    return env.createString(socket.remoteAddress().toString());
  }

  /**
   * Sets the socket data handler.
   */
  public NetSocket dataHandler(Env env, Value handler) {
    PhpTypes.assertCallable(env, handler, "Handler argument to Vertx\\Net\\NetSocket::dataHandler() must be callable.");
    socket.dataHandler(new Handler<org.vertx.java.core.buffer.Buffer>(env, PhpTypes.toCallable(handler)));
    return this;
  }

  /**
   * Pauses producing on the socket.
   */
  public NetSocket pause(Env env) {
    socket.pause();
    return this;
  }

  /**
   * Resumes producing on the socket.
   */
  public NetSocket resume(Env env) {
    socket.resume();
    return this;
  }

  /**
   * Sets the socket end handler.
   */
  public NetSocket endHandler(Env env, Value handler) {
    PhpTypes.assertCallable(env, handler, "Handler argument to Vertx\\Net\\NetSocket::endHandler() must be callable.");
    socket.endHandler(new Handler<Void>(env, PhpTypes.toCallable(handler)));
    return this;
  }

  /**
   * Sets the socket drain handler.
   */
  public NetSocket drainHandler(Env env, Value handler) {
    PhpTypes.assertCallable(env, handler, "Handler argument to Vertx\\Net\\NetSocket::drainHandler() must be callable.");
    socket.drainHandler(new Handler<Void>(env, PhpTypes.toCallable(handler)));
    return this;
  }

  /**
   * Sets the max write queue size.
   */
  public NetSocket writeQueueMaxSize(Env env, NumberValue value) {
    socket.setWriteQueueMaxSize(value.toInt());
    return this;
  }

  /**
   * Indicates whether the write queue is full.
   */
  public BooleanValue writeQueueFull(Env env) {
    return BooleanValue.create(socket.writeQueueFull());
  }

  /**
   * Writes a value to the socket.
   */
  public NetSocket write(Env env, Value value, StringValue enc) {
    socket.write(value.toString());
    return this;
  }

  /**
   * Sends a file through the socket.
   */
  public NetSocket sendFile(Env env, StringValue filename) {
    return this;
  }

  /**
   * Sets the socket close handler.
   */
  public void closeHandler(Env env, Value handler) {
    PhpTypes.assertCallable(env, handler, "Handler argument to Vertx\\Net\\NetSocket::closeHandler() must be callable.");
    socket.closeHandler(new Handler<Void>(env, PhpTypes.toCallable(handler)));
  }

  /**
   * Closes the socket.
   */
  public void close(Env env) {
    socket.close();
  }

  /**
   * Sets the socket exception handler callback.
   */
  public NetSocket exceptionHandler(Env env, Value handler) {
    PhpTypes.assertCallable(env, handler, "Handler argument to Vertx\\Net\\NetSocket::exceptionHandler() must be callable.");
    socket.exceptionHandler(new Handler<Throwable>(env, PhpTypes.toCallable(handler)));
    return this;
  }

  public String toString() {
    return "php:Vertx\\Net\\NetSocket";
  }

}

@@ -623,16 +623,58 @@
 p.net;%0A%0A
+import com.blankstyle.vertx.php.Gettable;%0A
 import c
@@ -1326,16 +1326,26 @@
 tSocket%3E
+, Gettable
  %7B%0A%0A  pr
@@ -1483,24 +1483,149 @@
 ocket;%0A  %7D%0A%0A
+  @Override%0A  public Value __getField(Env env, StringValue name) %7B%0A    return env.wrapJava(this).callMethod(env, name);%0A  %7D%0A%0A
   /**%0A   * R

Add __get method to NetSocket implementation.