/*
 * 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.rebind.model;

import com.google.gwt.autobean.shared.Splittable;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.javac.impl.JavaResourceBase;
import com.google.gwt.dev.javac.impl.MockJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.UnitTestTreeLogger;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.requestfactory.server.TestContextImpl;
import com.google.gwt.requestfactory.shared.EntityProxy;
import com.google.gwt.requestfactory.shared.InstanceRequest;
import com.google.gwt.requestfactory.shared.Locator;
import com.google.gwt.requestfactory.shared.ProxyFor;
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.RequestFactory;
import com.google.gwt.requestfactory.shared.Service;
import com.google.gwt.requestfactory.shared.ServiceLocator;
import com.google.gwt.requestfactory.shared.ValueProxy;

import junit.framework.TestCase;

import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;

/**
 * Test case for
 * {@link com.google.gwt.requestfactory.rebind.model.RequestFactoryModel} that
 * uses mock CompilationStates.
 */
public class RequestFactoryModelTest extends TestCase {

  /**
   * Constructs an empty interface representation of a type.
   */
  private static class EmptyMockJavaResource extends MockJavaResource {

    private final StringBuilder code = new StringBuilder();

    public EmptyMockJavaResource(Class<?> clazz) {
      super(clazz.getName());

      code.append("package ").append(clazz.getPackage().getName()).append(";\n");
      code.append("public interface ").append(clazz.getSimpleName());

      int numParams = clazz.getTypeParameters().length;
      if (numParams != 0) {
        code.append("<");
        for (int i = 0; i < numParams; i++) {
          if (i != 0) {
            code.append(",");
          }
          code.append("T").append(i);
        }
        code.append(">");
      }

      code.append("{}\n");
    }

    @Override
    protected CharSequence getContent() {
      return code;
    }
  }

  /**
   * Loads the actual source of a type. This should be used only for types
   * directly tested by this test. Note that use of this class requires your
   * source files to be on your classpath.
   */
  private static class RealJavaResource extends MockJavaResource {

    public RealJavaResource(Class<?> clazz) {
      super(clazz.getName());
    }

    @Override
    protected CharSequence getContent() {
      String resourceName = getTypeName().replace('.', '/') + ".java";
      InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(
          resourceName);
      return Util.readStreamAsString(stream);
    }
  }

  private static TreeLogger createCompileLogger() {
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
        System.err, true));
    logger.setMaxDetail(TreeLogger.ERROR);
    return logger;
  }

  private TreeLogger logger;

  @Override
  public void setUp() throws Exception {
    super.setUp();
    logger = createCompileLogger();
  }

  public void testBadCollectionType() {
    testModelWithMethodDecl(
        "Request<SortedSet<Integer>> badReturnType();",
        "Requests that return collections may be declared with java.util.List or java.util.Set only");
  }

  public void testBadCollectionTypeNotParameterized() {
    testModelWithMethodDecl("Request<SortedSet> badReturnType();",
        "Requests that return collections of List or Set must be parameterized");
  }

  public void testBadReturnType() {
    testModelWithMethodDecl("Request<Iterable> badReturnType();",
        "Invalid Request parameterization java.lang.Iterable");
  }

  public void testDuplicateBooleanGetters() {
    testModelWithMethodDecl("Request<t.ProxyWithRepeatedGetters> method();",
        "Duplicate accessors for property foo: getFoo() and isFoo()");
  }

  public void testMissingProxyFor() {
    testModelWithMethodDeclArgs("Request<TestProxy> okMethodProxy();",
        TestContextImpl.class.getName(), null,
        "The t.TestProxy type does not have a @ProxyFor, "
            + "@ProxyForName, or @JsonRpcProxy annotation");
  }

  public void testMissingService() {
    testModelWithMethodDeclArgs("Request<String> okMethod();", null,
        TestContextImpl.class.getName(),
        "RequestContext subtype t.TestContext is missing a "
            + "@Service or @JsonRpcService annotation");
  }

  public void testModelWithMethodDecl(final String clientMethodDecls,
      String... expected) {
    testModelWithMethodDeclArgs(clientMethodDecls,
        TestContextImpl.class.getName(), TestContextImpl.class.getName(),
        expected);
  }

  public void testModelWithMethodDeclArgs(final String clientMethodDecls,
      final String serviceClass, String proxyClass, String... expected) {
    Set<Resource> javaResources = getJavaResources(proxyClass);
    javaResources.add(new MockJavaResource("t.TestRequestFactory") {
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + RequestFactory.class.getName() + ";\n");
        code.append("interface TestRequestFactory extends RequestFactory {\n");
        code.append("TestContext testContext();");
        code.append("}");
        return code;
      }
    });
    javaResources.add(new MockJavaResource("t.TestContext") {
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + Request.class.getName() + ";\n");
        code.append("import " + InstanceRequest.class.getName() + ";\n");

        code.append("import " + RequestContext.class.getName() + ";\n");
        code.append("import " + SortedSet.class.getName() + ";\n");
        code.append("import " + List.class.getName() + ";\n");
        code.append("import " + Set.class.getName() + ";\n");
        code.append("import " + Service.class.getName() + ";\n");
        code.append("import " + TestContextImpl.class.getName() + ";\n");

        if (serviceClass != null) {
          code.append("@Service(" + serviceClass + ".class)");
        }
        code.append("interface TestContext extends RequestContext {\n");
        code.append(clientMethodDecls);
        code.append("}");
        return code;
      }
    });

    CompilationState state = CompilationStateBuilder.buildFrom(logger,
        javaResources);

    UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
    builder.setLowestLogLevel(TreeLogger.ERROR);
    for (String expectedMsg : expected) {
      builder.expectError(expectedMsg, null);
    }
    builder.expectError(RequestFactoryModel.poisonedMessage(), null);
    UnitTestTreeLogger testLogger = builder.createLogger();
    try {
      new RequestFactoryModel(testLogger, state.getTypeOracle().findType(
          "t.TestRequestFactory"));
      fail("Should have complained");
    } catch (UnableToCompleteException e) {
    }
    testLogger.assertCorrectLogEntries();
  }

  private Set<Resource> getJavaResources(final String proxyClass) {
    MockJavaResource[] javaFiles = {new MockJavaResource("t.AddressProxy") {
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + ProxyFor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        if (proxyClass != null) {
          code.append("@ProxyFor(" + proxyClass + ".class)");
        }
        code.append("interface TestProxy extends EntityProxy {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("t.ProxyWithRepeatedGetters") {
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package t;\n");
        code.append("import " + ProxyFor.class.getName() + ";\n");
        code.append("import " + EntityProxy.class.getName() + ";\n");
        if (proxyClass != null) {
          code.append("@ProxyFor(" + proxyClass + ".class)");
        }
        code.append("interface ProxyWithRepeatedGetters extends EntityProxy {\n");
        code.append("  boolean getFoo();");
        code.append("  boolean isFoo();");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("java.util.List") {
        // Tests a Driver interface that extends more than RFED
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package java.util;\n");
        code.append("public interface List<T> extends Collection<T> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("java.util.Set") {
        // Tests a Driver interface that extends more than RFED
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package java.util;\n");
        code.append("public interface Set<T> extends Collection<T> {\n");
        code.append("}");
        return code;
      }
    }, new MockJavaResource("java.util.SortedSet") {
        // Tests a Driver interface that extends more than RFED
      @Override
      protected CharSequence getContent() {
        StringBuilder code = new StringBuilder();
        code.append("package java.util;\n");
        code.append("public interface SortedSet<T> extends Set<T> {\n");
        code.append("}");
        return code;
      }
    }};

    Set<Resource> toReturn = new HashSet<Resource>(Arrays.asList(javaFiles));

    toReturn.addAll(Arrays.asList(new Resource[] {
        new EmptyMockJavaResource(Iterable.class),
        new EmptyMockJavaResource(EntityProxy.class),
        new EmptyMockJavaResource(InstanceRequest.class),
        new EmptyMockJavaResource(Locator.class),
        new EmptyMockJavaResource(RequestFactory.class),
        new EmptyMockJavaResource(Receiver.class),
        new EmptyMockJavaResource(ServiceLocator.class),
        new EmptyMockJavaResource(Splittable.class),
        new EmptyMockJavaResource(ValueProxy.class),

        new RealJavaResource(Request.class),
        new RealJavaResource(Service.class),
        new RealJavaResource(ProxyFor.class),
        new EmptyMockJavaResource(RequestContext.class),}));
    toReturn.addAll(Arrays.asList(JavaResourceBase.getStandardResources()));
    return toReturn;
  }
}
