package com.github.faucamp.simplertmp.packets;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.github.faucamp.simplertmp.amf.AmfNumber;
import com.github.faucamp.simplertmp.amf.AmfString;
import com.github.faucamp.simplertmp.io.ChunkStreamInfo;

/**
 * Encapsulates an command/"invoke" RTMP packet
 *
 * Invoke/command packet structure (AMF encoded):
 * (String) <commmand name>
 * (Number) <Transaction ID>
 * (Mixed) <Argument> ex. Null, String, Object: {key1:value1, key2:value2 ... }
 *
 * @author francois
 */
public class Command extends VariableBodyRtmpPacket {

  private static final String TAG = "Command";

  private String commandName;
  private int transactionId;

  public Command(RtmpHeader header) {
    super(header);
  }

  public Command(String commandName, int transactionId, ChunkStreamInfo channelInfo) {
    super(new RtmpHeader((channelInfo.canReusePrevHeaderTx(RtmpHeader.MessageType.COMMAND_AMF0)
        ? RtmpHeader.ChunkType.TYPE_1_RELATIVE_LARGE : RtmpHeader.ChunkType.TYPE_0_FULL),
        ChunkStreamInfo.RTMP_CID_OVER_CONNECTION, RtmpHeader.MessageType.COMMAND_AMF0));
    this.commandName = commandName;
    this.transactionId = transactionId;
  }

  public Command(String commandName, int transactionId) {
    super(new RtmpHeader(RtmpHeader.ChunkType.TYPE_0_FULL, ChunkStreamInfo.RTMP_CID_OVER_CONNECTION,
        RtmpHeader.MessageType.COMMAND_AMF0));
    this.commandName = commandName;
    this.transactionId = transactionId;
  }

  public String getCommandName() {
    return commandName;
  }

  public void setCommandName(String commandName) {
    this.commandName = commandName;
  }

  public int getTransactionId() {
    return transactionId;
  }

  public void setTransactionId(int transactionId) {
    this.transactionId = transactionId;
  }

  @Override
  public void readBody(InputStream in) throws IOException {
    // The command name and transaction ID are always present (AMF string followed by number)
    commandName = AmfString.readStringFrom(in, false);
    transactionId = (int) AmfNumber.readNumberFrom(in);
    int bytesRead = AmfString.sizeOf(commandName, false) + AmfNumber.SIZE;
    readVariableData(in, bytesRead);
  }

  @Override
  protected void writeBody(OutputStream out) throws IOException {
    AmfString.writeStringTo(out, commandName, false);
    AmfNumber.writeNumberTo(out, transactionId);
    // Write body data
    writeVariableData(out);
  }

  @Override
  protected byte[] array() {
    return null;
  }

  @Override
  protected int size() {
    return 0;
  }

  @Override
  public String toString() {
    return "RTMP Command (command: " + commandName + ", transaction ID: " + transactionId + ")";
  }
}

@@ -52,86 +52,53 @@
 ort 
-java.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.io.OutputStream;%0A
+com.github.faucamp.simplertmp.amf.AmfDecoder;
 %0Aimp
@@ -254,16 +254,101 @@
 eamInfo;
+%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.io.OutputStream;
 %0A%0A/**%0A *
@@ -2049,16 +2049,79 @@
 number)%0A
+    AmfString amfString = (AmfString) AmfDecoder.readFrom(in);%0A
     comm
@@ -2130,17 +2130,17 @@
 dName = 
-A
+a
 mfString
@@ -2144,34 +2144,169 @@
 ing.
-readStringFrom(in, false);
+getValue();%0A    //Sometimes only command name is received%0A    if (amfString.getSize() == header.getPacketLength()) %7B%0A      transactionId = 0;%0A      return;%0A    %7D
 %0A   

fix read command