/*
 * Copyright 2010 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.requestfactory.client.impl;

import com.google.gwt.core.client.JsArray;
import com.google.gwt.requestfactory.client.impl.messages.JsonResults;
import com.google.gwt.requestfactory.client.impl.messages.JsonServerException;
import com.google.gwt.requestfactory.client.impl.messages.RelatedObjects;
import com.google.gwt.requestfactory.client.impl.messages.RequestData;
import com.google.gwt.requestfactory.client.impl.messages.ReturnRecord;
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.InstanceRequest;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.requestfactory.shared.RequestContext;
import com.google.gwt.requestfactory.shared.ServerFailure;
import com.google.gwt.requestfactory.shared.Violation;
import com.google.gwt.requestfactory.shared.WriteOperation;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * <span style="color:red">Experimental API: This class is still under rapid
 * development, and is very likely to be deleted. Use it at your own risk.
 * </span>
 * </p>
 * Abstract implementation of {@link Request}. Each request stores a
 * {@link DeltaValueStoreJsonImpl}.
 * 
 * @param <T> return type
 */
public abstract class AbstractRequest<T> implements Request<T>,
    InstanceRequest<EntityProxy, T> {

  /**
   * Used by generated subtypes.
   */
  protected final Set<String> propertyRefs = new HashSet<String>();
  protected final AbstractRequestContext requestContext;
  private Receiver<? super T> receiver;
  private RequestData requestData;

  protected AbstractRequest(AbstractRequestContext requestContext) {
    this.requestContext = requestContext;
  }

  public void fire() {
    requestContext.fire();
  }

  public void fire(Receiver<? super T> receiver) {
    to(receiver);
    fire();
  }

  /**
   * @return the properties
   */
  public Set<String> getPropertyRefs() {
    return Collections.unmodifiableSet(propertyRefs);
  }

  public RequestData getRequestData() {
    if (requestData == null) {
      requestData = makeRequestData();
    }
    return requestData;
  }

  public void handleResponseText(String responseText) {
    JsonResults results = JsonResults.fromResults(responseText);
    JsonServerException cause = results.getException();
    if (cause != null) {
      fail(new ServerFailure(cause.getMessage(), cause.getType(),
          cause.getTrace()));
      return;
    }
    // handle violations
    JsArray<ReturnRecord> violationsArray = results.getViolations();
    if (violationsArray != null) {
      processViolations(violationsArray);
    } else {
      requestContext.processSideEffects(results.getSideEffects());
      processRelated(results.getRelated());
      if (results.isNullResult()) {
        // Indicates the server explicitly meant to send a null value
        succeed(null);
      } else {
        handleResult(results.getResult());
      }
    }
  }

  public RequestContext to(Receiver<? super T> receiver) {
    this.receiver = receiver;
    return requestContext;
  }

  /**
   * This method comes from the {@link InstanceRequest} interface. Instance
   * methods place the instance in the first parameter slot.
   */
  public Request<T> using(EntityProxy instanceObject) {
    getRequestData().getParameters()[0] = instanceObject;
    /*
     * Instance methods enqueue themselves when their using() method is called.
     * This ensures that the instance parameter will have been set when
     * AbstractRequestContext.retainArg() is called.
     */
    requestContext.addInvocation(this);
    return this;
  }

  public Request<T> with(String... propertyRefs) {
    this.propertyRefs.addAll(Arrays.asList(propertyRefs));
    return this;
  }

  /**
   * This method is called by generated subclasses to process the main return
   * property of the JSON payload. The return record isn't just a reference to a
   * persist or update side-effect, so it has to be processed separately.
   */
  protected <Q extends EntityProxy> Q decodeReturnObject(Class<Q> clazz,
      Object obj) {
    ReturnRecord jso = (ReturnRecord) obj;
    SimpleEntityProxyId<Q> id = requestContext.getRequestFactory().getId(clazz,
        jso.getSimpleId());
    Q proxy = requestContext.processReturnRecord(id, (ReturnRecord) obj,
        WriteOperation.UPDATE);
    return proxy;
  }

  protected <Q extends EntityProxy> void decodeReturnObjectList(
      Class<Q> elementType, Object obj, Collection<Q> accumulator) {
    @SuppressWarnings("unchecked")
    JsArray<ReturnRecord> array = (JsArray<ReturnRecord>) obj;
    for (int i = 0, j = array.length(); i < j; i++) {
      ReturnRecord record = array.get(i);
      if (record == null) {
        accumulator.add(null);
        continue;
      }

      // Decode the individual object
      Q decoded = decodeReturnObject(elementType, record);

      // Really want Class.isInstance()
      assert elementType.equals(decoded.stableId().getProxyClass());
      accumulator.add(decoded);
    }
  }

  protected <Q> void decodeReturnValueList(Class<Q> elementType, Object obj,
      Collection<Q> accumulator) {
    @SuppressWarnings("unchecked")
    List<Q> temp = (List<Q>) EntityCodex.decode(List.class, elementType,
        requestContext, obj);
    accumulator.addAll(temp);
  }

  protected void fail(ServerFailure failure) {
    requestContext.reuse();
    if (receiver != null) {
      receiver.onFailure(failure);
    }
  }

  /**
   * Process the response and call {@link #succeed(Object) or
   * #fail(com.google.gwt.requestfactory.shared.ServerFailure).
   */
  protected abstract void handleResult(Object result);

  protected boolean hasReceiver() {
    return receiver != null;
  }

  protected abstract RequestData makeRequestData();

  protected void processRelated(RelatedObjects related) {
    for (String token : related.getHistoryTokens()) {
      SimpleEntityProxyId<EntityProxy> id = requestContext.getRequestFactory().getProxyId(
          token);
      requestContext.processReturnRecord(id, related.getReturnRecord(token));
    }
  }

  protected void succeed(T t) {
    // The user may not have called to()
    if (receiver != null) {
      receiver.onSuccess(t);
    }
  }

  private void processViolations(JsArray<ReturnRecord> violationsArray) {
    int length = violationsArray.length();
    Set<Violation> errors = new HashSet<Violation>(length);

    for (int i = 0; i < length; i++) {
      ReturnRecord violationRecord = violationsArray.get(i);
      final EntityProxyId<?> key = requestContext.getRequestFactory().getId(
          violationRecord.getSchema(), violationRecord.getEncodedId(),
          violationRecord.getFutureId());

      HashMap<String, String> violations = new HashMap<String, String>();
      assert violationRecord.hasViolations();
      violationRecord.fillViolations(violations);

      for (Map.Entry<String, String> entry : violations.entrySet()) {
        final String path = entry.getKey();
        final String message = entry.getValue();
        errors.add(new Violation() {
          public String getMessage() {
            return message;
          }

          public String getPath() {
            return path;
          }

          public EntityProxyId<?> getProxyId() {
            return key;
          }
        });
      }
    }

    requestContext.reuse();
    requestContext.addErrors(errors);
    if (receiver != null) {
      receiver.onViolation(errors);
    }
  }
}
