/*
 * 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.shared.impl;

import com.google.gwt.autobean.shared.AutoBeanFactory;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.EntityProxyId;
import com.google.gwt.requestfactory.shared.ProxySerializer;
import com.google.gwt.requestfactory.shared.ProxyStore;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.requestfactory.shared.RequestFactory;
import com.google.gwt.requestfactory.shared.RequestTransport;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Base type for generated RF interfaces.
 */
public abstract class AbstractRequestFactory extends IdFactory implements
    RequestFactory {
  private static final int MAX_VERSION_ENTRIES = 10000;

  private EventBus eventBus;

  @SuppressWarnings("serial")
  private final Map<String, String> version = new LinkedHashMap<String, String>(
      16, 0.75f, true) {
    @Override
    protected boolean removeEldestEntry(Entry<String, String> eldest) {
      return size() > MAX_VERSION_ENTRIES;
    }
  };
  private RequestTransport transport;

  public <P extends EntityProxy> Request<P> find(final EntityProxyId<P> proxyId) {
    if (((SimpleEntityProxyId<P>) proxyId).isEphemeral()) {
      throw new IllegalArgumentException("Cannot fetch unpersisted entity");
    }

    AbstractRequestContext context = new AbstractRequestContext(
        AbstractRequestFactory.this, AbstractRequestContext.Dialect.STANDARD) {
      @Override
      protected AutoBeanFactory getAutoBeanFactory() {
        return AbstractRequestFactory.this.getAutoBeanFactory();
      }
    };
    return new AbstractRequest<P>(context) {
      {
        requestContext.addInvocation(this);
      }

      @Override
      protected RequestData makeRequestData() {
        return new RequestData(
            "com.google.gwt.requestfactory.shared.impl.FindRequest::find",
            new Object[] {proxyId}, propertyRefs, proxyId.getProxyClass(), null);
      }
    };
  }

  public EventBus getEventBus() {
    return eventBus;
  }

  public String getHistoryToken(Class<? extends EntityProxy> clazz) {
    return getTypeToken(clazz);
  }

  public String getHistoryToken(EntityProxyId<?> proxy) {
    return getHistoryToken((SimpleProxyId<?>) proxy);
  }

  public Class<? extends EntityProxy> getProxyClass(String historyToken) {
    String typeToken = IdUtil.getTypeToken(historyToken);
    if (typeToken != null) {
      return getTypeFromToken(typeToken);
    }
    return getTypeFromToken(historyToken);
  }

  @SuppressWarnings("unchecked")
  public <T extends EntityProxy> EntityProxyId<T> getProxyId(String historyToken) {
    return (EntityProxyId<T>) getBaseProxyId(historyToken);
  }

  public RequestTransport getRequestTransport() {
    return transport;
  }

  public ProxySerializer getSerializer(ProxyStore store) {
    return new ProxySerializerImpl(this, store);
  }

  /**
   * The choice of a default request transport is runtime-specific.
   */
  public abstract void initialize(EventBus eventBus);

  public void initialize(EventBus eventBus, RequestTransport transport) {
    this.eventBus = eventBus;
    this.transport = transport;
  }

  /**
   * Implementations of EntityProxies are provided by an AutoBeanFactory, which
   * is itself a generated type. This method knows about all proxy types used in
   * the RequestFactory interface, which prevents pruning of any proxy type. If
   * the {@link #find(EntityProxyId)} and {@link #getSerializer(ProxyStore)}
   * were provided by {@link AbstractRequestContext}, this method could be
   * removed.
   */
  protected abstract AutoBeanFactory getAutoBeanFactory();

  /**
   * Used by {@link AbstractRequestContext} to quiesce update events for objects
   * that haven't truly changed.
   */
  protected boolean hasVersionChanged(SimpleProxyId<?> id,
      String observedVersion) {
    assert id != null : "id";
    assert observedVersion != null : "observedVersion";
    String key = getHistoryToken(id);
    String existingVersion = version.get(key);
    // Return true if we haven't seen this before or the versions differ
    boolean toReturn = existingVersion == null
        || !existingVersion.equals(observedVersion);
    if (toReturn) {
      version.put(key, observedVersion);
    }
    return toReturn;
  }
}
