/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.testing.client.runner;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.scout.commons.exception.ProcessingException;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
import org.eclipse.scout.commons.serialization.SerializationUtility;
import org.eclipse.scout.rt.client.IClientSession;
import org.eclipse.scout.rt.testing.shared.runner.TestEnvironmentUtility;
import org.eclipse.scout.rt.testing.shared.services.common.exceptionhandler.ProcessingRuntimeExceptionUnwrappingStatement;
import org.eclipse.scout.testing.client.DefaultTestClientSessionProvider;
import org.eclipse.scout.testing.client.ITestClientSessionProvider;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

/**
 * JUnit test runner that runs the annotated test class within a Scout client job. Test cases executed by this runner
 * may be configured with a {@link ClientTest} annotation.
 * <p/>
 * <h3>Custom Test Environments</h3> A custom test environment (e.g. required for running Tests with Maven Tycho) can be
 * set up using an implementation of {@link IClientTestEnvironment} which must be on the classpath of
 * {@link SerializationUtility#getClassLoader()}. The custom {@link IClientTestEnvironment} class must use the following
 * <b>fully qualified</b> class name:
 * <p/>
 * <code>org.eclipse.scout.testing.client.runner.CustomClientTestEnvironment</code>
 */
public class ScoutClientTestRunner extends BlockJUnit4ClassRunner {

  private static ITestClientSessionProvider s_defaultClientSessionProvider = new DefaultTestClientSessionProvider();
  private static Class<? extends IClientSession> s_defaultClientSessionClass;
  private static final IScoutLogger LOG;
  private static final IClientTestEnvironment CLIENT_TEST_ENVIRONMENT;

  static {
    LOG = ScoutLogManager.getLogger(ScoutClientTestRunner.class);
    CLIENT_TEST_ENVIRONMENT = TestEnvironmentUtility.createTestEnvironment(
        IClientTestEnvironment.class,
        "org.eclipse.scout.testing.client.runner.customClientTestEnvironmentClassName",
        "org.eclipse.scout.testing.client.runner.CustomClientTestEnvironment");

    if (CLIENT_TEST_ENVIRONMENT != null) {
      CLIENT_TEST_ENVIRONMENT.setupGlobalEnvironment();
    }
  }

  private final IClientSession m_clientSession;

  @Retention(RetentionPolicy.RUNTIME)
  @Target({ElementType.TYPE, ElementType.METHOD})
  public @interface ClientTest {

    Class<? extends IClientSession> clientSessionClass() default IClientSession.class;

    Class<? extends ITestClientSessionProvider> sessionProvider() default NullTestClientSessionProvider.class;

    String runAs() default "";

    boolean forceNewSession() default false;
  }

  /**
   * Null-provider used as default value in the {@link ClientTest} annotation (since annotation values must not be
   * <code>null</code>).
   */
  public interface NullTestClientSessionProvider extends ITestClientSessionProvider {
  }

  /**
   * @param klass
   * @throws InitializationError
   */
  public ScoutClientTestRunner(Class<?> klass) throws InitializationError {
    super(klass);

    if (CLIENT_TEST_ENVIRONMENT != null) {
      CLIENT_TEST_ENVIRONMENT.setupInstanceEnvironment();
    }

    try {
      m_clientSession = getOrCreateClientSession(klass.getAnnotation(ClientTest.class), null);
    }
    catch (InitializationError e) {
      throw e;
    }
    catch (Exception e) {
      List<Throwable> errors = new ArrayList<Throwable>();
      errors.add(e);
      throw new InitializationError(errors);
    }
  }

  public static ITestClientSessionProvider getDefaultClientSessionProvider() {
    return s_defaultClientSessionProvider;
  }

  public static void setDefaultClientSessionProvider(ITestClientSessionProvider defaultClientSessionProvider) {
    s_defaultClientSessionProvider = defaultClientSessionProvider;
  }

  public static Class<? extends IClientSession> getDefaultClientSessionClass() {
    return s_defaultClientSessionClass;
  }

  public static void setDefaultClientSessionClass(Class<? extends IClientSession> defaultClientSessionClass) {
    s_defaultClientSessionClass = defaultClientSessionClass;
  }

  /**
   * @return Returns the default client session class used by this test runner. Defaults to
   *         {@link #getDefaultClientSessionClass()}. Subclasses may override this method to provide another default
   *         value.
   */
  protected Class<? extends IClientSession> defaultClientSessionClass() {
    return getDefaultClientSessionClass();
  }

  /**
   * @return Returns the default client session provider used by this test runner. Defaults to
   *         {@link #getDefaultClientSessionProvider()}. Subclasses may override this method to provide another default
   *         value.
   */
  protected ITestClientSessionProvider defaultClientSessionProvider() {
    return getDefaultClientSessionProvider();
  }

  @Override
  protected Statement withBeforeClasses(Statement statement) {
    // run all methods annotated with @BeforeClass in a separate ServerSession
    List<FrameworkMethod> befores = getTestClass().getAnnotatedMethods(BeforeClass.class);
    return befores.isEmpty() ? statement : new RunBeforesInSeparateScoutClientSession(m_clientSession, statement, befores, null);
  }

  @Override
  protected Statement withAfterClasses(Statement statement) {
    // run all methods annotated with @AfterClass in a separate ServerSession
    List<FrameworkMethod> afters = getTestClass().getAnnotatedMethods(AfterClass.class);
    return afters.isEmpty() ? statement : new RunAftersInSeparateScoutClientSession(m_clientSession, statement, afters, null);
  }

  @Override
  protected Statement methodBlock(FrameworkMethod method) {
    try {
      // run each test method in a separate ClientSession
      IClientSession clientSession = getClientSession(method);
      return createWrappedStatement(super.methodBlock(method), clientSession);
    }
    catch (final ProcessingException e1) {
      return new Statement() {
        @Override
        public void evaluate() throws Throwable {
          throw e1;
        }
      };
    }

  }

  protected IClientSession getClientSession(FrameworkMethod method) throws ProcessingException {
    ClientTest methodLevelClientTest = method.getAnnotation(ClientTest.class);
    if (methodLevelClientTest != null) {
      try {
        ClientTest classLevelClientTest = getTestClass().getJavaClass().getAnnotation(ClientTest.class);
        return getOrCreateClientSession(classLevelClientTest, methodLevelClientTest);
      }
      catch (final Throwable e) {
        throw new ProcessingException("Could not create ClientSession", e);
      }
    }
    return m_clientSession;
  }

  protected Statement createWrappedStatement(Statement statement, IClientSession session) {
    return new ScoutClientJobWrapperStatement(session, statement);
  }

  @Override
  @SuppressWarnings("deprecation")
  protected Statement possiblyExpectingExceptions(FrameworkMethod method, Object test, Statement next) {
    // unpack wrapped ProcessingExceptions and rethrow them
    return super.possiblyExpectingExceptions(method, test, new ProcessingRuntimeExceptionUnwrappingStatement(next));
  }

  protected IClientSession getOrCreateClientSession(ClientTest classLevelClientTest, ClientTest methodLevelClientTest) throws Exception {
    // process default values
    Class<? extends IClientSession> clientSessionClass = defaultClientSessionClass();
    ITestClientSessionProvider sessionProvider = defaultClientSessionProvider();
    String runAs = null;
    boolean forceNewSession = false;

    // process class-level client test configuration
    if (classLevelClientTest != null) {
      clientSessionClass = extractClientSessionClass(classLevelClientTest, clientSessionClass);
      sessionProvider = extractSessionProvider(classLevelClientTest, sessionProvider);
      runAs = extractRunAs(classLevelClientTest, runAs);
      forceNewSession = extractForceNewSession(classLevelClientTest, forceNewSession);
    }

    // process method-level client test configuration
    if (methodLevelClientTest != null) {
      clientSessionClass = extractClientSessionClass(methodLevelClientTest, clientSessionClass);
      sessionProvider = extractSessionProvider(methodLevelClientTest, sessionProvider);
      runAs = extractRunAs(methodLevelClientTest, runAs);
      forceNewSession = extractForceNewSession(methodLevelClientTest, forceNewSession);
    }

    // sanity check
    if (clientSessionClass == null) {
      throw new InitializationError("Client session class is not set. Either set the default client session using '"
          + ScoutClientTestRunner.class.getSimpleName()
          + ".setDefaultClientSessionClass' or annotate your test class and/or method with '"
          + ClientTest.class.getSimpleName() + "'");
    }

    // return existing or create new client session
    return sessionProvider.getOrCreateClientSession(clientSessionClass, runAs, forceNewSession);
  }

  /**
   * @param clientTest
   * @return
   */
  protected Class<? extends IClientSession> extractClientSessionClass(ClientTest clientTest, Class<? extends IClientSession> defaultValue) {
    if (clientTest == null || clientTest.clientSessionClass() == null || clientTest.clientSessionClass() == IClientSession.class) {
      return defaultValue;
    }
    return clientTest.clientSessionClass();
  }

  /**
   * @param clientTest
   * @return
   */
  protected ITestClientSessionProvider extractSessionProvider(ClientTest clientTest, ITestClientSessionProvider defaultValue) throws Exception {
    if (clientTest == null || clientTest.sessionProvider() == null || clientTest.sessionProvider() == NullTestClientSessionProvider.class) {
      return defaultValue;
    }
    return clientTest.sessionProvider().newInstance();
  }

  /**
   * @param clientTest
   * @return
   */
  protected String extractRunAs(ClientTest clientTest, String defaultValue) {
    String runAs = defaultValue;
    if (clientTest != null && clientTest.runAs() != null) {
      String s = clientTest.runAs().trim();
      if (s.length() > 0) {
        runAs = s;
      }
    }
    return runAs;
  }

  /**
   * @param clientTest
   * @return
   */
  protected boolean extractForceNewSession(ClientTest clientTest, boolean defaultValue) {
    boolean forceCreateNewSession = defaultValue;
    if (clientTest != null) {
      forceCreateNewSession = clientTest.forceNewSession();
    }
    return forceCreateNewSession;
  }
}
