/*
 * Copyright (c) 2008-2014 Eike Stepper (Berlin, Germany) and others.
 * 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:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.tests.config.impl;

import org.eclipse.emf.cdo.common.model.EMFUtil;
import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSessionConfiguration;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoChangeSets;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoCommitInfos;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoDurableLocking;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoExternalReferences;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoFeatureMaps;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoHandleRevisions;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoLargeObjects;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoQueryXRefs;
import org.eclipse.emf.cdo.spi.server.InternalStore.NoRawAccess;
import org.eclipse.emf.cdo.tests.config.IConstants;
import org.eclipse.emf.cdo.tests.config.IModelConfig;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.config.IScenario;
import org.eclipse.emf.cdo.tests.config.ISessionConfig;
import org.eclipse.emf.cdo.tests.config.impl.SessionConfig.Net4j;
import org.eclipse.emf.cdo.tests.mango.MangoFactory;
import org.eclipse.emf.cdo.tests.mango.MangoPackage;
import org.eclipse.emf.cdo.tests.model1.Model1Factory;
import org.eclipse.emf.cdo.tests.model1.Model1Package;
import org.eclipse.emf.cdo.tests.model2.Model2Factory;
import org.eclipse.emf.cdo.tests.model2.Model2Package;
import org.eclipse.emf.cdo.tests.model3.Model3Factory;
import org.eclipse.emf.cdo.tests.model3.Model3Package;
import org.eclipse.emf.cdo.tests.model3.subpackage.SubpackageFactory;
import org.eclipse.emf.cdo.tests.model3.subpackage.SubpackagePackage;
import org.eclipse.emf.cdo.tests.model4.model4Factory;
import org.eclipse.emf.cdo.tests.model4.model4Package;
import org.eclipse.emf.cdo.tests.model4interfaces.model4interfacesPackage;
import org.eclipse.emf.cdo.tests.model5.Model5Factory;
import org.eclipse.emf.cdo.tests.model5.Model5Package;
import org.eclipse.emf.cdo.tests.model6.Model6Factory;
import org.eclipse.emf.cdo.tests.model6.Model6Package;

import org.eclipse.net4j.util.ImplementationError;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.container.IManagedContainer;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.security.IPasswordCredentials;
import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
import org.eclipse.net4j.util.security.PasswordCredentialsProvider;
import org.eclipse.net4j.util.tests.AbstractOMTest;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import junit.framework.TestResult;

/**
 * @author Eike Stepper
 */
public abstract class ConfigTest extends AbstractOMTest implements IConstants
{
  private static int dynamicPackageCounter;

  private transient int dynamicPackageNumber;

  private IScenario scenario;

  private Properties homeProperties;

  private Map<String, Object> testProperties;

  public ConfigTest()
  {
  }

  public synchronized IScenario getScenario()
  {
    if (scenario == null)
    {
      setScenario(getDefaultScenario());
    }

    return scenario;
  }

  public synchronized void setScenario(IScenario scenario)
  {
    this.scenario = scenario;
    if (scenario != null)
    {
      scenario.setCurrentTest(this);
    }
  }

  public synchronized Properties getHomeProperties()
  {
    if (homeProperties == null)
    {
      homeProperties = new Properties();
      String home = System.getProperty("user.home");
      if (home != null)
      {
        File file = new File(home, ".cdo_config_test.properties");
        if (file.exists())
        {
          FileInputStream stream = IOUtil.openInputStream(file);

          try
          {
            homeProperties.load(stream);
          }
          catch (IOException ex)
          {
            throw WrappedException.wrap(ex);
          }
          finally
          {
            IOUtil.close(stream);
          }
        }
      }
    }

    return homeProperties;
  }

  public synchronized void setHomeProperties(Properties homeProperties)
  {
    this.homeProperties = homeProperties;
  }

  public synchronized Map<String, Object> getTestProperties()
  {
    if (testProperties == null)
    {
      testProperties = new HashMap<String, Object>();
    }

    return testProperties;
  }

  // /////////////////////////////////////////////////////////////////////////
  // //////////////////////// Repository /////////////////////////////////////

  /**
   * @category Repository
   */
  public IRepositoryConfig getRepositoryConfig()
  {
    IScenario scenario = getScenario();
    return scenario.getRepositoryConfig();
  }

  /**
   * @category Repository
   */
  public Map<String, String> getRepositoryProperties()
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    return repositoryConfig.getRepositoryProperties();
  }

  /**
   * @category Repository
   */
  public boolean hasServerContainer()
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    return repositoryConfig.hasServerContainer();
  }

  /**
   * @category Repository
   */
  public IManagedContainer getServerContainer()
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    return repositoryConfig.getServerContainer();
  }

  /**
   * @category Repository
   */
  public InternalRepository getRepository(String name, boolean activate)
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    return repositoryConfig.getRepository(name, activate);
  }

  /**
   * @category Repository
   */
  public InternalRepository getRepository(String name)
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    return repositoryConfig.getRepository(name);
  }

  /**
   * @category Repository
   */
  public InternalRepository getRepository()
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    return repositoryConfig.getRepository(IRepositoryConfig.REPOSITORY_NAME);
  }

  /**
   * @category Repository
   */
  public void registerRepository(IRepository repository)
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();
    repositoryConfig.registerRepository((InternalRepository)repository);
  }

  /**
   * @category Repository
   */
  public InternalRepository restartRepository()
  {
    return restartRepository(IRepositoryConfig.REPOSITORY_NAME);
  }

  /**
   * @category Repository
   */
  public InternalRepository restartRepository(String name)
  {
    IRepositoryConfig repositoryConfig = getRepositoryConfig();

    try
    {
      repositoryConfig.setRestarting(true);
      InternalRepository repo = getRepository(name);
      LifecycleUtil.deactivate(repo);
      return getRepository(name);
    }
    finally
    {
      repositoryConfig.setRestarting(false);
    }
  }

  // /////////////////////////////////////////////////////////////////////////
  // //////////////////////// Session ////////////////////////////////////////

  /**
   * @category Session
   */
  public ISessionConfig getSessionConfig()
  {
    IScenario scenario = getScenario();
    return scenario.getSessionConfig();
  }

  /**
   * @category Session
   */
  public boolean hasClientContainer()
  {
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.hasClientContainer();
  }

  /**
   * @category Session
   */
  public IManagedContainer getClientContainer()
  {
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.getClientContainer();
  }

  /**
   * @category Session
   */
  public void startTransport() throws Exception
  {
    ISessionConfig sessionConfig = getSessionConfig();
    sessionConfig.startTransport();
  }

  /**
   * @category Session
   */
  public String getTransportType() throws Exception
  {
    ISessionConfig sessionConfig = getSessionConfig();
    if (sessionConfig instanceof Net4j)
    {
      Net4j net4j = (Net4j)sessionConfig;
      return net4j.getTransportType();
    }

    return null;
  }

  /**
   * @category Session
   */
  public void stopTransport() throws Exception
  {
    ISessionConfig sessionConfig = getSessionConfig();
    sessionConfig.stopTransport();
  }

  /**
   * @category Session
   */
  public String getURIProtocol()
  {
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.getURIProtocol();
  }

  /**
   * @category Session
   */
  public String getURIPrefix()
  {
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.getURIPrefix();
  }

  /**
   * @category Session
   */
  public CDOSession openSession()
  {
    determineCodeLink();
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.openSession();
  }

  /**
   * @category Session
   */
  public CDOSession openSession(String repositoryName)
  {
    determineCodeLink();
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.openSession(repositoryName);
  }

  /**
   * @category Session
   */
  public CDOSession openSession(CDOSessionConfiguration configuration)
  {
    determineCodeLink();
    ISessionConfig sessionConfig = getSessionConfig();
    return sessionConfig.openSession(configuration);
  }

  /**
   * @category Session
   */
  public CDOSession openSession(IPasswordCredentials credentials)
  {
    if (credentials != null)
    {
      IPasswordCredentialsProvider credentialsProvider = new PasswordCredentialsProvider(credentials);
      getTestProperties().put(SessionConfig.PROP_TEST_CREDENTIALS_PROVIDER, credentialsProvider);
    }
    else
    {
      getTestProperties().remove(SessionConfig.PROP_TEST_CREDENTIALS_PROVIDER);
    }

    return openSession();
  }

  // /////////////////////////////////////////////////////////////////////////
  // //////////////////////// Model //////////////////////////////////////////

  /**
   * @category Model
   */
  public IModelConfig getModelConfig()
  {
    IScenario scenario = getScenario();
    return scenario.getModelConfig();
  }

  /**
   * @category Model
   */
  public MangoFactory getMangoFactory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getMangoFactory();
  }

  /**
   * @category Model
   */
  public MangoPackage getMangoPackage()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getMangoPackage();
  }

  /**
   * @category Model
   */
  public Model1Factory getModel1Factory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel1Factory();
  }

  /**
   * @category Model
   */
  public Model1Package getModel1Package()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel1Package();
  }

  /**
   * @category Model
   */
  public Model2Factory getModel2Factory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel2Factory();
  }

  /**
   * @category Model
   */
  public Model2Package getModel2Package()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel2Package();
  }

  /**
   * @category Model
   */
  public Model3Factory getModel3Factory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel3Factory();
  }

  /**
   * @category Model
   */
  public Model3Package getModel3Package()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel3Package();
  }

  /**
   * @category Model
   */
  public SubpackageFactory getModel3SubpackageFactory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel3SubPackageFactory();
  }

  /**
   * @category Model
   */
  public SubpackagePackage getModel3SubpackagePackage()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel3SubPackagePackage();
  }

  /**
   * @category Model
   */
  public model4Factory getModel4Factory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel4Factory();
  }

  /**
   * @category Model
   */
  public model4Package getModel4Package()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel4Package();
  }

  /**
   * @category Model
   */
  public model4interfacesPackage getModel4InterfacesPackage()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel4InterfacesPackage();
  }

  /**
   * @category Model
   */
  public Model5Factory getModel5Factory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel5Factory();
  }

  /**
   * @category Model
   */
  public Model5Package getModel5Package()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel5Package();
  }

  /**
   * @category Model
   */
  public Model6Factory getModel6Factory()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel6Factory();
  }

  /**
   * @category Model
   */
  public Model6Package getModel6Package()
  {
    IModelConfig modelConfig = getModelConfig();
    return modelConfig.getModel6Package();
  }

  // /////////////////////////////////////////////////////////////////////////
  // /////////////////////////////////////////////////////////////////////////

  public boolean isValid()
  {
    return true;
  }

  @Override
  public String toString()
  {
    return MessageFormat.format("{0}.{1} [{2}, {3}, {4}]", getClass().getSimpleName(), getName(),
        getRepositoryConfig(), getSessionConfig(), getModelConfig());
  }

  @Override
  public TestResult run()
  {
    try
    {
      return super.run();
    }
    catch (ConfigTestException ex)
    {
      throw ex;
    }
    catch (Throwable ex)
    {
      throw new ConfigTestException("Error in " + this, ex);
    }
  }

  @Override
  public void runBare() throws Throwable
  {
    try
    {
      super.runBare();
    }
    catch (AssertionError error)
    {
      throw error;
    }
    catch (Throwable ex)
    {
      // We wrap anything that is not a test failure
      throw new ConfigTestException("Error in " + this, ex);
    }
  }

  /**
   * Constructs a test-specific resource path of the format "/TestClass_testMethod/resourceName". Using this instead of
   * (just) a hardcoded name for the test resource, ensures that the test method is isolated from all others at the
   * resource level.
   *
   * @param resourceName
   *          the test-local name of the resource or <code>null</code> for the path of the test-local root resource.
   * @return the full path of the resource.
   */
  public final String getResourcePath(String resourceName)
  {
    StringBuilder builder = new StringBuilder();
    builder.append('/');
    builder.append(getClass().getSimpleName()); // Name of this test class
    builder.append('_');
    builder.append(getName()); // Name of the executing test method

    if (resourceName == null || resourceName.length() == 0 || resourceName.charAt(0) != '/')
    {
      builder.append('/');
    }

    if (resourceName != null)
    {
      builder.append(resourceName);
    }

    return builder.toString();
  }

  /**
   * Constructs a test-specific EPackage of the format "pkg123_name". Using this instead of
   * (just) a hardcoded name for the test package, ensures that the test method is isolated from all others.
   *
   * @param name
   *          the test-local name of the package or <code>null</code> .
   * @return the created package.
   * @see #createUniquePackage()
   */
  public final EPackage createUniquePackage(String name)
  {
    if (dynamicPackageNumber == 0)
    {
      dynamicPackageNumber = ++dynamicPackageCounter;
    }

    StringBuilder builder = new StringBuilder();
    builder.append("pkg");
    builder.append(dynamicPackageNumber);

    if (name != null)
    {
      builder.append('_');
      builder.append(name);
    }

    final String uniqueName = builder.toString();

    EPackage ePackage = EMFUtil.createEPackage(uniqueName, uniqueName, "http://" + uniqueName);
    ePackage.eAdapters().add(new AdapterImpl()
    {
      @Override
      public void notifyChanged(Notification msg)
      {
        if (msg.isTouch())
        {
          return;
        }

        Object feature = msg.getFeature();
        if (feature == EcorePackage.Literals.EPACKAGE__NS_PREFIX || feature == EcorePackage.Literals.EPACKAGE__NS_URI
            || feature == EcorePackage.Literals.ENAMED_ELEMENT__NAME)
        {
          throw new ImplementationError("Don't change the unique package " + uniqueName);
        }
      }
    });

    return ePackage;
  }

  /**
   * @see #createUniquePackage(String)
   */
  public final EPackage createUniquePackage()
  {
    return createUniquePackage(null);
  }

  protected boolean isConfig(Config config)
  {
    return ObjectUtil.equals(getRepositoryConfig(), config) //
        || ObjectUtil.equals(getSessionConfig(), config) //
        || ObjectUtil.equals(getModelConfig(), config);
  }

  protected void skipStoreWithoutExternalReferences()
  {
    skipTest(getRepository().getStore() instanceof NoExternalReferences);
  }

  protected void skipStoreWithoutQueryXRefs()
  {
    skipTest(getRepository().getStore() instanceof NoQueryXRefs);
  }

  protected void skipStoreWithoutLargeObjects()
  {
    skipTest(getRepository().getStore() instanceof NoLargeObjects);
  }

  protected void skipStoreWithoutFeatureMaps()
  {
    skipTest(getRepository().getStore() instanceof NoFeatureMaps);
  }

  protected void skipStoreWithoutHandleRevisions()
  {
    skipTest(getRepository().getStore() instanceof NoHandleRevisions);
  }

  protected void skipStoreWithoutRawAccess()
  {
    skipTest(getRepository().getStore() instanceof NoRawAccess);
  }

  protected void skipStoreWithoutChangeSets()
  {
    skipTest(getRepository().getStore() instanceof NoChangeSets);
  }

  protected void skipStoreWithoutCommitInfos()
  {
    skipTest(getRepository().getStore() instanceof NoCommitInfos);
  }

  protected void skipStoreWithoutDurableLocking()
  {
    skipTest(getRepository().getStore() instanceof NoDurableLocking);
  }

  protected void clearCache(CDORevisionManager revisionManager)
  {
    ((InternalCDORevisionManager)revisionManager).getCache().clear();
  }

  public void restartScenario() throws Exception
  {
    IOUtil.OUT().println("RESTARTING SCENARIO");
    stopTransport();

    IScenario scenario = getScenario();
    scenario.tearDown();
    scenario.setUp();

    startTransport();
    IOUtil.OUT().println("RESTARTING SCENARIO - FINISHED");
  }

  protected IScenario getDefaultScenario()
  {
    IScenario scenario;

    try
    {
      scenario = Scenario.load();
      if (scenario == null)
      {
        scenario = Scenario.getDefault();
      }
    }
    catch (Exception ex)
    {
      scenario = Scenario.getDefault();
    }

    return scenario;
  }

  @Override
  public void setUp() throws Exception
  {
    getScenario();
    super.setUp();
  }

  @Override
  protected void doSetUp() throws Exception
  {
    super.doSetUp();
    getScenario().setUp();
  }

  @Override
  protected void doTearDown() throws Exception
  {
    try
    {
      getScenario().tearDown();

      if (testProperties != null)
      {
        testProperties.clear();
        testProperties = null;
      }

      if (homeProperties != null)
      {
        homeProperties.clear();
        homeProperties = null;
      }
    }
    catch (Exception ex)
    {
      IOUtil.print(ex);
    }

    try
    {
      super.doTearDown();
    }
    catch (Exception ex)
    {
      IOUtil.print(ex);
    }
  }

  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ ElementType.TYPE, ElementType.METHOD })
  public @interface CleanRepositoriesBefore
  {
    String reason();
  }

  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ ElementType.TYPE, ElementType.METHOD })
  public @interface CleanRepositoriesAfter
  {
    String reason();
  }

  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ ElementType.TYPE, ElementType.METHOD })
  public @interface Requires
  {
    String[] value();
  }

  @Inherited
  @Retention(RetentionPolicy.RUNTIME)
  @Target({ ElementType.TYPE, ElementType.METHOD })
  public @interface Skips
  {
    String[] value();
  }
}
