package org.swellrt.beta.client.operation.impl;

import org.swellrt.beta.client.ServiceContext;
import org.swellrt.beta.client.operation.Operation;
import org.swellrt.beta.common.SException;
import org.swellrt.beta.model.SObject;
import org.swellrt.beta.model.remote.SObjectRemote;
import org.waveprotocol.wave.concurrencycontrol.common.ResponseCode;
import org.waveprotocol.wave.model.id.InvalidIdException;
import org.waveprotocol.wave.model.id.ModernIdSerialiser;
import org.waveprotocol.wave.model.id.WaveId;

import com.google.common.util.concurrent.FutureCallback;

import jsinterop.annotations.JsProperty;
import jsinterop.annotations.JsType;

public final class OpenOperation implements Operation<OpenOperation.Options, OpenOperation.Response> {
   
  
  @JsType(isNative = true)
  public interface Options extends Operation.Options {
    
    @JsProperty
    public String getId();
  }
  
  @JsType
  public interface Response extends Operation.Response {
    
    @JsProperty
    public SObject getController();
    
    @JsProperty
    public Object getObject();
    
  }
  
  private final ServiceContext context;
  
  public OpenOperation(ServiceContext context) {
    this.context = context;
  }
  

  @Override
  public void execute(Options options, Callback<Response> callback) {

    try {
            
      if (!context.isSession()) {
    	if (callback != null)
        	callback.onError(new SException(ResponseCode.NOT_LOGGED_IN));
      }
        
      WaveId waveId = null;
      if (options.getId() != null) {
        waveId = ModernIdSerialiser.INSTANCE.deserialiseWaveId(options.getId());
      } else {
        waveId = context.generateWaveId();
      }

      context.getObject(waveId, new FutureCallback<SObjectRemote>() {

        @Override
        public void onSuccess(SObjectRemote result) {

          callback.onSuccess(new OpenOperation.Response() {
            @Override
            public SObject getController() {
              return result;
            }

            @Override
            public Object getObject() {
              return result.asNative();
            }

          });

        }

        @Override
        public void onFailure(Throwable e) {
          if (e instanceof SException) {
            callback.onError((SException) e); 
           } else {
            callback.onError(new SException(SException.OPERATION_EXCEPTION, e));
           }
          
        }
        
      });
      

    } catch (InvalidIdException e) {
      callback.onError(new SException(ResponseCode.INVALID_ID));
    }

  }

}

@@ -1496,20 +1496,28 @@
 ;%0A      
-if (
+String id = 
 options.
@@ -1527,19 +1527,164 @@
 Id()
- != null) %7B
+;%0A      // Wave domain part is optional%0A      if (id != null) %7B%0A        if (!id.contains(%22/%22)) %7B%0A          id = context.getWaveDomain()+ %22/%22 + id;%0A        %7D
 %0A   
@@ -1743,31 +1743,18 @@
 eWaveId(
-options.getId()
+id
 );%0A     

Allow optional domain part in object ids