/*
 * Copyright 2013 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.web.bindery.requestfactory.gwt.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.web.bindery.event.shared.SimpleEventBus;
import com.google.web.bindery.requestfactory.shared.ProxyFor;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
import com.google.web.bindery.requestfactory.shared.Service;
import com.google.web.bindery.requestfactory.shared.SkipInterfaceValidation;
import com.google.web.bindery.requestfactory.shared.ValueProxy;

import java.util.Collections;
import java.util.List;

/**
 * Tests usage of generics in RequestFactory.
 */
@SkipInterfaceValidation
public class RequestFactoryGenericsTest extends GWTTestCase {

  /** Service under test. */
  public static class Impl {
    public static Domain echoDomain(Domain domainObject) {
      return domainObject;
    }

    public static BaseDomain<?, ?> getBase() {
      return new BaseDomain<Integer, Float>() {
        {
          setListOfStrings(Collections.singletonList("foo"));
        }

        @Override
        public void setA(Integer a) {
          throw new UnsupportedOperationException();
        }

        @Override
        public Integer getA() {
          throw new UnsupportedOperationException();
        }

        @Override
        public List<Integer> getListOfA() {
          throw new UnsupportedOperationException();
        }

        @Override
        public void setListOfA(List<Integer> list) {
          throw new UnsupportedOperationException();
        }
      };
    }

    public static Container echoContainer(Container container) {
      return container;
    }
  }

  /** Generic interface implemented by both proxy and domain object. */
  public interface HasA<A> {
    A getA();

    void setA(A a);

    List<A> getListOfA();

    void setListOfA(List<A> list);
  }

  /** Base generic domain object. */
  public static abstract class BaseDomain<A, B> implements HasA<A> {
    private B b;
    private List<String> listOfStrings;

    public B getB() {
      return b;
    }

    public void setB(B b) {
      this.b = b;
    }

    public List<String> getListOfStrings() {
      return this.listOfStrings;
    }

    public void setListOfStrings(List<String> list) {
      this.listOfStrings = list;
    }
  }

  /** Domain object that "locks" generic type params from base class. */
  public static class Domain extends BaseDomain<String, Boolean> {
    private String str;
    private List<String> list;

    @Override
    public String getA() {
      return str;
    }

    @Override
    public void setA(String a) {
      str = a;
    }

    @Override
    public List<String> getListOfA() {
      return list;
    }

    @Override
    public void setListOfA(List<String> list) {
      this.list = list;
    }
  }

  /** Domain object containing another object with inherited generics. */
  public static class Container {
    private Domain domain;

    public Domain getDomain() {
      return domain;
    }

    public void setDomain(Domain domain) {
      this.domain = domain;
    }
  }

  /** Proxy testing that the domain type can be parameterized. */
  @ProxyFor(BaseDomain.class)
  public interface BaseDomainProxy extends ValueProxy {
    List<String> getListOfStrings();

    void setListOfStrings(List<String> listOfStrings);
  }

  /** Proxy implementing generic interface (locking the type param). */
  @ProxyFor(Domain.class)
  public interface DomainProxy extends BaseDomainProxy, HasA<String> {

    Boolean getB();

    void setB(Boolean b);
  }

  /** Base interface references proxy "with generics". */
  public interface BaseContainerProxy {
    BaseDomainProxy getDomain();
  }

  /**
   * Child-interface overrides method with co-variant return type (with
   * "locked" type params).
   */
  @ProxyFor(Container.class)
  public interface ContainerProxy extends ValueProxy, BaseContainerProxy {

    @Override
    DomainProxy getDomain();

    void setDomain(DomainProxy domain);
  }

  /** Request context under test. */
  @Service(Impl.class)
  public interface Context extends RequestContext {
    Request<DomainProxy> echoDomain(DomainProxy proxy);

    Request<BaseDomainProxy> getBase();

    Request<ContainerProxy> echoContainer(ContainerProxy container);
  }

  /** Factory under test. */
  public interface Factory extends RequestFactory {
    Context ctx();
  }

  @Override
  public String getModuleName() {
    return "com.google.web.bindery.requestfactory.gwt.RequestFactorySuite";
  }

  private static final int TEST_DELAY = 5000;

  protected Factory factory;

  public void testEchoDomain() throws Exception {
    delayTestFinish(TEST_DELAY);
    Context ctx = factory.ctx();
    DomainProxy proxy = ctx.create(DomainProxy.class);
    proxy.setA("foo");
    proxy.setB(true);
    proxy.setListOfA(Collections.singletonList("bar"));
    proxy.setListOfStrings(Collections.singletonList("baz"));
    ctx.echoDomain(proxy).fire(new Receiver<DomainProxy>() {
      @Override
      public void onSuccess(DomainProxy response) {
        assertEquals("foo", response.getA());
        assertEquals(Boolean.TRUE, response.getB());
        assertEquals(Collections.singletonList("bar"), response.getListOfA());
        assertEquals(Collections.singletonList("baz"), response.getListOfStrings());
        finishTest();
      }
    });
  }

  public void testGetBase() throws Exception {
    delayTestFinish(TEST_DELAY);
    Context ctx = factory.ctx();
    ctx.getBase().fire(new Receiver<BaseDomainProxy>() {
      @Override
      public void onSuccess(BaseDomainProxy response) {
        assertEquals(Collections.singletonList("foo"), response.getListOfStrings());
        finishTest();
      }
    });
  }

  public void testEchoContainer() throws Exception {
    delayTestFinish(TEST_DELAY);
    Context ctx = factory.ctx();
    DomainProxy proxy = ctx.create(DomainProxy.class);
    proxy.setA("42");
    ContainerProxy container = ctx.create(ContainerProxy.class);
    container.setDomain(proxy);
    ctx.echoContainer(container).fire(new Receiver<ContainerProxy>() {
      @Override
      public void onSuccess(ContainerProxy response) {
        assertEquals("42", response.getDomain().getA());
        finishTest();
      }
    });
  }

  @Override
  protected void gwtSetUp() throws Exception {
    factory = createFactory();
  }

  protected Factory createFactory() {
    Factory factory = GWT.create(Factory.class);
    factory.initialize(new SimpleEventBus());
    return factory;
  }
}
