/*
 * Copyright 2009 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * 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.google.gwt.rpc.client.impl;

import com.google.gwt.core.client.GWT;
import com.google.gwt.rpc.client.ast.ArrayValueCommand;
import com.google.gwt.rpc.client.ast.BooleanValueCommand;
import com.google.gwt.rpc.client.ast.ByteValueCommand;
import com.google.gwt.rpc.client.ast.CharValueCommand;
import com.google.gwt.rpc.client.ast.CommandSink;
import com.google.gwt.rpc.client.ast.DoubleValueCommand;
import com.google.gwt.rpc.client.ast.EnumValueCommand;
import com.google.gwt.rpc.client.ast.FloatValueCommand;
import com.google.gwt.rpc.client.ast.InstantiateCommand;
import com.google.gwt.rpc.client.ast.IntValueCommand;
import com.google.gwt.rpc.client.ast.InvokeCustomFieldSerializerCommand;
import com.google.gwt.rpc.client.ast.LongValueCommand;
import com.google.gwt.rpc.client.ast.NullValueCommand;
import com.google.gwt.rpc.client.ast.ReturnCommand;
import com.google.gwt.rpc.client.ast.RpcCommand;
import com.google.gwt.rpc.client.ast.RpcCommandVisitor;
import com.google.gwt.rpc.client.ast.SetCommand;
import com.google.gwt.rpc.client.ast.ShortValueCommand;
import com.google.gwt.rpc.client.ast.StringValueCommand;
import com.google.gwt.rpc.client.ast.ThrowCommand;
import com.google.gwt.rpc.client.ast.ValueCommand;
import com.google.gwt.user.client.rpc.SerializationException;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * This implementation of CommandSink encodes RpcCommands in a simple transport
 * format that can be interpreted by both the client and the server.
 */
public class SimplePayloadSink extends CommandSink {

  private class Visitor extends RpcCommandVisitor {

    @Override
    public void endVisit(BooleanValueCommand x, Context ctx) {
      appendTypedData(BOOLEAN_TYPE, x.getValue() ? "1" : "0");
    }

    @Override
    public void endVisit(ByteValueCommand x, Context ctx) {
      appendTypedData(BYTE_TYPE, x.getValue().toString());
    }

    @Override
    public void endVisit(CharValueCommand x, Context ctx) {
      appendTypedData(CHAR_TYPE, String.valueOf((int) x.getValue()));
    }

    @Override
    public void endVisit(DoubleValueCommand x, Context ctx) {
      appendTypedData(DOUBLE_TYPE, x.getValue().toString());
    }

    @Override
    public void endVisit(EnumValueCommand x, Context ctx) {
      // ETypeSeedName~IOrdinal~
      if (appendIdentity(x)) {
        appendTypedData(ENUM_TYPE, x.getValue().getDeclaringClass().getName());
        // use ordinal (and not name), since name might have been obfuscated
        appendTypedData(INT_TYPE, String.valueOf(x.getValue().ordinal()));
      }
    }

    @Override
    public void endVisit(FloatValueCommand x, Context ctx) {
      appendTypedData(FLOAT_TYPE, x.getValue().toString());
    }

    @Override
    public void endVisit(IntValueCommand x, Context ctx) {
      appendTypedData(INT_TYPE, x.getValue().toString());
    }

    @Override
    public void endVisit(LongValueCommand x, Context ctx) {
      appendTypedData(LONG_TYPE, x.getValue().toString());
    }

    @Override
    public void endVisit(NullValueCommand x, Context ctx) {
      appendTypedData(VOID_TYPE, "");
    }

    @Override
    public void endVisit(ShortValueCommand x, Context ctx) {
      appendTypedData(SHORT_TYPE, x.getValue().toString());
    }

    @Override
    public void endVisit(StringValueCommand x, Context ctx) {
      // "4~abcd
      if (appendIdentity(x)) {
        String value = x.getValue();
        /*
         * Emit this a a Pascal-style string, using an explicit length. This
         * avoids the need to escape the value.
         */
        appendTypedData(STRING_TYPE, String.valueOf(value.length()));
        append(value);
      }
    }

    @Override
    public boolean visit(ArrayValueCommand x, Context ctx) {
      /*
       * Encoded as (leafType, dimensions, length, .... )
       * 
       * Object[] foo = new Object[3];
       * 
       * becomes
       * 
       * [ObjectSeedname~1~3~@....~@....~@...~
       * 
       * Object[][] foo = new Object[3][];
       * 
       * becomes
       * 
       * [ObjectSeedName~2~3~...three one-dim arrays...
       */
      if (appendIdentity(x)) {
        int dims = 1;
        Class<?> leaf = x.getComponentType();
        while (leaf.getComponentType() != null) {
          dims++;
          leaf = leaf.getComponentType();
        }

        appendTypedData(ARRAY_TYPE, leaf.getName());
        accept(new IntValueCommand(dims));
        accept(new IntValueCommand(x.getComponentValues().size()));
        return true;
      } else {
        return false;
      }
    }

    @Override
    public boolean visit(InstantiateCommand x, Context ctx) {
      // @TypeSeedName~3~... N-many setters ...
      if (appendIdentity(x)) {
        appendTypedData(OBJECT_TYPE, x.getTargetClass().getName());
        accept(new IntValueCommand(x.getSetters().size()));
        return true;
      } else {
        return false;
      }
    }

    @Override
    public boolean visit(InvokeCustomFieldSerializerCommand x, Context ctx) {
      // !TypeSeedName~Number of objects written by CFS~...CFS objects...~
      // Number of extra fields~...N-many setters...
      if (appendIdentity(x)) {
        appendTypedData(INVOKE_TYPE, x.getTargetClass().getName());
        accept(new IntValueCommand(x.getValues().size()));
        accept(x.getValues());
        accept(new IntValueCommand(x.getSetters().size()));
        accept(x.getSetters());
        return false;
      } else {
        return false;
      }
    }

    @Override
    public boolean visit(ReturnCommand x, Context ctx) {
      // R4~...values...
      appendTypedData(RETURN_TYPE, String.valueOf(x.getValues().size()));
      return true;
    }

    @Override
    public boolean visit(SetCommand x, Context ctx) {
      /*
       * In hosted-mode, the field's declaring class is written to the stream to
       * handle field shadowing. In web mode, this isn't necessary because all
       * field names are allocated in the same "object" scope.
       * 
       * DeclaringClassName~FieldName~...value...
       */
      if (!GWT.isScript()) {
        accept(new StringValueCommand(x.getFieldDeclClass().getName()));
      }
      accept(new StringValueCommand(x.getField()));
      return true;
    }

    @Override
    public boolean visit(ThrowCommand x, Context ctx) {
      // T...value...
      appendTypedData(THROW_TYPE, "");
      return true;
    }

    private void append(String x) {
      try {
        buffer.append(EscapeUtil.escape(x)).append(RPC_SEPARATOR_CHAR);
      } catch (IOException e) {
        halt(e);
      }
    }

    private boolean appendIdentity(ValueCommand x) {
      Integer backRef = backRefs.get(x);
      if (backRef != null) {
        if (PRETTY) {
          try {
            buffer.append(NL_CHAR);
          } catch (IOException e) {
            halt(e);
          }
        }
        append(BACKREF_TYPE + String.valueOf(backRef));
        return false;
      } else {
        backRefs.put(x, backRefs.size());
        return true;
      }
    }

    private void appendTypedData(char type, String value) {
      try {
        if (PRETTY) {
          buffer.append(NL_CHAR);
        }
        buffer.append(type).append(value).append(RPC_SEPARATOR_CHAR);
      } catch (IOException e) {
        halt(e);
      }
    }
  }

  /**
   * Used for diagnostics.
   */
  static final boolean PRETTY = false;

  public static final char ARRAY_TYPE = '[';
  public static final char BACKREF_TYPE = '@';
  public static final char BOOLEAN_TYPE = 'Z';
  public static final char BYTE_TYPE = 'B';
  public static final char CHAR_TYPE = 'C';
  public static final char DOUBLE_TYPE = 'D';
  public static final char ENUM_TYPE = 'E';
  public static final char FLOAT_TYPE = 'F';
  public static final char INT_TYPE = 'I';
  public static final char INVOKE_TYPE = '!';
  public static final char LONG_TYPE = 'J';
  public static final char NL_CHAR = '\n';
  public static final char OBJECT_TYPE = 'L';
  public static final char RETURN_TYPE = 'R';
  public static final char RPC_SEPARATOR_CHAR = '~';
  public static final char SHORT_TYPE = 'S';
  public static final char STRING_TYPE = '"';
  public static final char THROW_TYPE = 'T';
  public static final char VOID_TYPE = 'V';

  private final Map<ValueCommand, Integer> backRefs = new HashMap<ValueCommand, Integer>();

  private final Appendable buffer;

  public SimplePayloadSink(Appendable buffer) {
    this.buffer = buffer;
  }

  @Override
  public void accept(RpcCommand command) throws SerializationException {
    (new Visitor()).accept(command);
  }

  @Override
  public void finish() throws SerializationException {
  }
}
