/*
 *  Copyright 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import java.nio.ByteBuffer;

/** Java wrapper for a C++ DataChannelInterface. */
public class DataChannel {
  /** Java wrapper for WebIDL RTCDataChannel. */
  public static class Init {
    public boolean ordered = true;
    // Optional unsigned short in WebIDL, -1 means unspecified.
    public int maxRetransmitTimeMs = -1;
    // Optional unsigned short in WebIDL, -1 means unspecified.
    public int maxRetransmits = -1;
    public String protocol = "";
    public boolean negotiated;
    // Optional unsigned short in WebIDL, -1 means unspecified.
    public int id = -1;

    @CalledByNative
    boolean getOrdered() {
      return ordered;
    }

    @CalledByNative
    int getMaxRetransmitTimeMs() {
      return maxRetransmitTimeMs;
    }

    @CalledByNative
    int getMaxRetransmits() {
      return maxRetransmits;
    }

    @CalledByNative
    String getProtocol() {
      return protocol;
    }

    @CalledByNative
    boolean getNegotiated() {
      return negotiated;
    }

    @CalledByNative
    int getId() {
      return id;
    }
  }

  /** Java version of C++ DataBuffer.  The atom of data in a DataChannel. */
  public static class Buffer {
    /** The underlying data. */
    public final ByteBuffer data;

    /**
     * Indicates whether `data` contains UTF-8 text or "binary data"
     * (i.e. anything else).
     */
    public final boolean binary;

    @CalledByNative
    public Buffer(ByteBuffer data, boolean binary) {
      this.data = data;
      this.binary = binary;
    }
  }

  /** Java version of C++ DataChannelObserver. */
  public interface Observer {
    /** The data channel's bufferedAmount has changed. */
    @CalledByNative public void onBufferedAmountChange(long previousAmount);
    /** The data channel state has changed. */
    @CalledByNative public void onStateChange();
    /**
     * A data buffer was successfully received.  NOTE: `buffer.data` will be
     * freed once this function returns so callers who want to use the data
     * asynchronously must make sure to copy it first.
     */
    @CalledByNative public void onMessage(Buffer buffer);
  }

  /** Keep in sync with DataChannelInterface::DataState. */
  public enum State {
    CONNECTING,
    OPEN,
    CLOSING,
    CLOSED;

    @CalledByNative
    static State fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  private long nativeDataChannel;
  private long nativeObserver;

  @CalledByNative
  public DataChannel(long nativeDataChannel) {
    this.nativeDataChannel = nativeDataChannel;
  }

  /** Register `observer`, replacing any previously-registered observer. */
  public void registerObserver(Observer observer) {
    checkDataChannelExists();
    if (nativeObserver != 0) {
      nativeUnregisterObserver(nativeObserver);
    }
    nativeObserver = nativeRegisterObserver(observer);
  }

  /** Unregister the (only) observer. */
  public void unregisterObserver() {
    checkDataChannelExists();
    nativeUnregisterObserver(nativeObserver);
    nativeObserver = 0;
  }

  public String label() {
    checkDataChannelExists();
    return nativeLabel();
  }

  public int id() {
    checkDataChannelExists();
    return nativeId();
  }

  public State state() {
    checkDataChannelExists();
    return nativeState();
  }

  /**
   * Return the number of bytes of application data (UTF-8 text and binary data)
   * that have been queued using SendBuffer but have not yet been transmitted
   * to the network.
   */
  public long bufferedAmount() {
    checkDataChannelExists();
    return nativeBufferedAmount();
  }

  /** Close the channel. */
  public void close() {
    checkDataChannelExists();
    nativeClose();
  }

  /** Send `data` to the remote peer; return success. */
  public boolean send(Buffer buffer) {
    checkDataChannelExists();
    // TODO(fischman): this could be cleverer about avoiding copies if the
    // ByteBuffer is direct and/or is backed by an array.
    byte[] data = new byte[buffer.data.remaining()];
    buffer.data.get(data);
    return nativeSend(data, buffer.binary);
  }

  /** Dispose of native resources attached to this channel. */
  public void dispose() {
    checkDataChannelExists();
    JniCommon.nativeReleaseRef(nativeDataChannel);
    nativeDataChannel = 0;
  }

  @CalledByNative
  long getNativeDataChannel() {
    return nativeDataChannel;
  }

  private void checkDataChannelExists() {
    if (nativeDataChannel == 0) {
      throw new IllegalStateException("DataChannel has been disposed.");
    }
  }

  private native long nativeRegisterObserver(Observer observer);
  private native void nativeUnregisterObserver(long observer);
  private native String nativeLabel();
  private native int nativeId();
  private native State nativeState();
  private native long nativeBufferedAmount();
  private native void nativeClose();
  private native boolean nativeSend(byte[] data, boolean binary);
}
