/*
 * Copyright (c) 2008-2013 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:
 *    Simon McDuff - initial API and implementation
 *    Eike Stepper - maintenance
 */
package org.eclipse.emf.cdo.tests;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOObjectReference;
import org.eclipse.emf.cdo.common.id.CDOIDExternal;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionData;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.internal.net4j.protocol.LoadRevisionsRequest;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.config.IModelConfig;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
import org.eclipse.emf.cdo.tests.model1.Supplier;
import org.eclipse.emf.cdo.tests.model2.Model2Package;
import org.eclipse.emf.cdo.tests.model4.GenRefSingleNonContained;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.transaction.CDOXATransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.util.DanglingReferenceException;
import org.eclipse.emf.cdo.view.CDOViewSet;

import org.eclipse.net4j.signal.ISignalProtocol;
import org.eclipse.net4j.signal.SignalCounter;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.emf.ecore.xmi.impl.XMLResourceFactoryImpl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;

/**
 * @author Simon McDuff
 */
public class ExternalReferenceTest extends AbstractCDOTest
{
  private static final String REPOSITORY_B_NAME = "repo2";

  public void testExternalWithDynamicEObject() throws Exception
  {
    skipStoreWithoutExternalReferences();

    ResourceSet resourceSet = new ResourceSetImpl();
    resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("test", new XMIResourceFactoryImpl());

    CDOSession sessionA = openSession();
    sessionA.getPackageRegistry().putEPackage(getModel4InterfacesPackage());
    sessionA.getPackageRegistry().putEPackage(getModel4Package());
    CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);

    CDOResource resA = transactionA1.createResource(getResourcePath("/resA"));
    Resource resD = resourceSet.createResource(URI.createURI("test://1"));

    EPackage schoolPackage = createDynamicEPackage();
    resourceSet.getPackageRegistry().put(schoolPackage.getNsURI(), schoolPackage);

    EClass eClass = (EClass)schoolPackage.getEClassifier("SchoolBook");
    EObject schoolbook = EcoreUtil.create(eClass);

    GenRefSingleNonContained objectFromResA = getModel4Factory().createGenRefSingleNonContained();
    objectFromResA.setElement(schoolbook);
    resD.getContents().add(schoolbook);

    resA.getContents().add(objectFromResA);
    transactionA1.commit();
  }

  public void testExternalWithEClass() throws Exception
  {
    skipStoreWithoutExternalReferences();

    {
      ResourceSet resourceSet = new ResourceSetImpl();

      CDOSession sessionA = openSession();
      sessionA.getPackageRegistry().putEPackage(getModel4InterfacesPackage());
      sessionA.getPackageRegistry().putEPackage(getModel4Package());
      CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);

      CDOResource resA = transactionA1.createResource(getResourcePath("/resA"));
      GenRefSingleNonContained objectFromResA = getModel4Factory().createGenRefSingleNonContained();
      objectFromResA.setElement(getModel1Package().getAddress());
      resA.getContents().add(objectFromResA);
      transactionA1.commit();
    }

    clearCache(getRepository().getRevisionManager());

    {
      CDOSession sessionA = openSession();
      ResourceSet resourceSet = new ResourceSetImpl();
      resourceSet.getPackageRegistry().put(getModel1Package().getNsURI(), getModel1Package());

      CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
      CDOResource resA = transactionA1.getResource(getResourcePath("/resA"));

      GenRefSingleNonContained objectFromResA = (GenRefSingleNonContained)resA.getContents().get(0);
      assertEquals(getModel1Package().getAddress(), objectFromResA.getElement());
      transactionA1.commit();
    }
  }

  public void testExternalWithEPackage() throws Exception
  {
    skipStoreWithoutExternalReferences();

    {
      CDOSession sessionA = openSession();

      ResourceSet resourceSet = new ResourceSetImpl();

      sessionA.getPackageRegistry().putEPackage(getModel4Package());
      sessionA.getPackageRegistry().putEPackage(getModel4InterfacesPackage());

      CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
      CDOResource resA = transactionA1.createResource(getResourcePath("/resA"));
      GenRefSingleNonContained objectFromResA = getModel4Factory().createGenRefSingleNonContained();
      objectFromResA.setElement(getModel1Package());
      resA.getContents().add(objectFromResA);
      transactionA1.commit();
    }

    clearCache(getRepository().getRevisionManager());

    {
      CDOSession sessionA = openSession();

      ResourceSet resourceSet = new ResourceSetImpl();
      resourceSet.getPackageRegistry().put(getModel1Package().getNsURI(), getModel1Package());

      CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
      CDOResource resA = transactionA1.getResource(getResourcePath("/resA"));

      GenRefSingleNonContained objectFromResA = (GenRefSingleNonContained)resA.getContents().get(0);
      assertEquals(getModel1Package(), objectFromResA.getElement());
      transactionA1.commit();
    }
  }

  // XXX disabled because of Bug 290097
  @Skips("Postgresql")
  public void testOneXMIResourceManyViewsOnOneResourceSet() throws Exception
  {
    skipStoreWithoutExternalReferences();

    byte[] dataOfresD = null;
    getRepository(REPOSITORY_B_NAME);

    {
      CDOSession sessionA = openSession();
      CDOSession sessionB = openSession(REPOSITORY_B_NAME);
      ResourceSet resourceSet = new ResourceSetImpl();
      resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("test", new XMIResourceFactoryImpl());

      sessionA.getPackageRegistry().putEPackage(getModel1Package());
      sessionA.getPackageRegistry().putEPackage(Model2Package.eINSTANCE);
      sessionB.getPackageRegistry().putEPackage(getModel1Package());
      sessionB.getPackageRegistry().putEPackage(Model2Package.eINSTANCE);

      CDOTransaction transactionA1 = sessionA.openTransaction(resourceSet);
      CDOTransaction transactionB1 = sessionB.openTransaction(resourceSet);

      CDOResource resA = transactionA1.createResource(getResourcePath("/resA"));
      CDOResource resB = transactionB1.createResource(getResourcePath("/resB"));

      EList<Resource> resources = resourceSet.getResources();
      assertEquals(2, resources.size());// Bug 346636

      CDOResource resC = transactionA1.createResource(getResourcePath("/resC"));
      assertNotNull(resC);
      assertEquals(3, resources.size());// Bug 346636

      Resource resD = resourceSet.createResource(URI.createURI("test://1"));
      assertEquals(4, resources.size());// Bug 346636
      assertEquals(false, resD instanceof CDOResource);

      Company companyA = getModel1Factory().createCompany();
      companyA.setName("VALUEA");

      Company companyB = getModel1Factory().createCompany();
      companyB.setName("VALUEB");

      Company companyD = getModel1Factory().createCompany();
      companyD.setName("VALUED");

      resD.getContents().add(companyD);
      resA.getContents().add(companyA);
      resB.getContents().add(companyB);

      Supplier supplier = getModel1Factory().createSupplier();
      PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();

      supplier.getPurchaseOrders().add(purchaseOrder);
      resD.getContents().add(supplier);
      resA.getContents().add(purchaseOrder);

      CDOXATransaction transSet = CDOUtil.createXATransaction();

      transSet.add(CDOUtil.getViewSet(resourceSet));

      transactionA1.commit();

      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      resD.save(outputStream, null);
      dataOfresD = outputStream.toByteArray();
    }

    clearCache(getRepository().getRevisionManager());

    {
      ResourceSet resourceSet = new ResourceSetImpl();
      CDOSession session = openSession();
      CDOTransaction transaction = session.openTransaction(resourceSet);

      CDOSession session2 = openSession(REPOSITORY_B_NAME);
      CDOTransaction transaction2 = session2.openTransaction(resourceSet);

      CDOViewSet set = CDOUtil.getViewSet(resourceSet);
      assertNotNull(set);

      resourceSet.getPackageRegistry().put(getModel1Package().getNsURI(), getModel1Package());
      resourceSet.getResourceFactoryRegistry().getProtocolToFactoryMap().put("test", new XMIResourceFactoryImpl());

      Resource resD = resourceSet.createResource(URI.createURI("test://1"));
      resD.load(new ByteArrayInputStream(dataOfresD), null);

      CDOResource resA = transaction.getResource(getResourcePath("/resA"));
      CDOResource resB = transaction2.getResource(getResourcePath("/resB"));
      Company companyA = (Company)resA.getContents().get(0);
      Company companyB = (Company)resB.getContents().get(0);
      Company companyD = (Company)resD.getContents().get(0);

      assertNotSame(resA.getURI(), resB.getURI());
      assertNotSame(resA.getPath(), "/resA");
      assertNotSame(resB.getPath(), "/resB");
      assertNotSame(resA.cdoView(), transaction2);
      assertNotSame(resB.cdoView(), transaction);

      assertEquals("VALUEA", companyA.getName());
      assertEquals("VALUEB", companyB.getName());
      assertEquals("VALUED", companyD.getName());

      Supplier supplierD = (Supplier)resD.getContents().get(1);
      PurchaseOrder pO = supplierD.getPurchaseOrders().get(0);
      assertEquals(transaction, CDOUtil.getCDOObject(pO).cdoView());
      assertEquals(supplierD, pO.getSupplier());
    }
  }

  // Skip this test until the problems with XATransactions are solved.
  // XXX disabled because of Bug 290097
  @Skips({ IModelConfig.CAPABILITY_LEGACY, "Postgresql" })
  public void testManyViewsOnOneResourceSet() throws Exception
  {
    skipStoreWithoutExternalReferences();

    getRepository(REPOSITORY_B_NAME);

    {
      CDOSession session = openSession();
      session.getPackageRegistry().putEPackage(getModel1Package());

      CDOSession sessionB = openSession(REPOSITORY_B_NAME);

      ResourceSet resourceSet = new ResourceSetImpl();
      CDOTransaction transaction = session.openTransaction(resourceSet);
      CDOTransaction transactionB = sessionB.openTransaction(resourceSet);

      CDOResource res = transaction.createResource(getResourcePath("/resA"));
      CDOResource resB = transactionB.createResource(getResourcePath("/resB"));

      PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();
      Supplier supplier = getModel1Factory().createSupplier();
      supplier.getPurchaseOrders().add(purchaseOrder);

      resB.getContents().add(supplier);
      res.getContents().add(purchaseOrder);

      CDOXATransaction transSet = CDOUtil.createXATransaction();
      transSet.add(CDOUtil.getViewSet(resourceSet));

      transaction.commit();
    }

    clearCache(getRepository().getRevisionManager());

    {
      ResourceSet resourceSet = new ResourceSetImpl();
      CDOSession sessionA = openSession();
      CDOTransaction transactionA = sessionA.openTransaction(resourceSet);

      CDOSession sessionB = openSession(REPOSITORY_B_NAME);
      CDOTransaction transactionB = sessionB.openTransaction(resourceSet);

      CDOResource resA = transactionA.getResource(getResourcePath("/resA"));
      assertNotNull(resA);

      CDOResource resB = transactionB.getResource(getResourcePath("/resB"));
      assertNotNull(resB);

      Supplier supplierB = (Supplier)resB.getContents().get(0);
      PurchaseOrder pO = supplierB.getPurchaseOrders().get(0);

      assertEquals(transactionA, CDOUtil.getCDOObject(pO).cdoView());

      assertEquals(transactionB, CDOUtil.getCDOObject(supplierB).cdoView());

      assertEquals(supplierB, pO.getSupplier());
      assertEquals(supplierB.getPurchaseOrders().get(0), pO);
    }
  }

  public void testObjectNotAttached() throws Exception
  {
    msg("Opening session");
    CDOSession session = openSession();

    msg("Opening transaction");
    CDOTransaction transaction = session.openTransaction();

    msg("Creating resource");
    CDOResource resource1 = transaction.createResource(getResourcePath("/test1"));

    msg("Adding company");
    Supplier supplier = getModel1Factory().createSupplier();
    PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();
    supplier.getPurchaseOrders().add(purchaseOrder);

    resource1.getContents().add(supplier);

    try
    {
      msg("Committing");
      transaction.commit();
      fail("CommitException expected");
    }
    catch (CommitException success)
    {
      assertEquals(true, success.getCause() instanceof DanglingReferenceException);
      assertSame(purchaseOrder, ((DanglingReferenceException)success.getCause()).getTarget());
    }
  }

  public void testUsingObjectsBetweenSameTransaction() throws Exception
  {
    CDOSession session = openSession();

    CDOTransaction transaction1 = session.openTransaction();
    CDOTransaction transaction2 = session.openTransaction();

    CDOResource resource1 = transaction1.createResource(getResourcePath("/test1"));
    CDOResource resource2 = transaction2.createResource(getResourcePath("/test2"));

    Supplier supplier = getModel1Factory().createSupplier();
    PurchaseOrder purchaseOrder = getModel1Factory().createPurchaseOrder();
    supplier.getPurchaseOrders().add(purchaseOrder);

    resource1.getContents().add(supplier);
    resource2.getContents().add(purchaseOrder);

    transaction1.commit();
  }

  public void testWithXML() throws Exception
  {
    skipStoreWithoutExternalReferences();

    ResourceSet resourceSet = new ResourceSetImpl();
    Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
    map.put("xml", new XMLResourceFactoryImpl());

    PurchaseOrder externalObject = getModel1Factory().createPurchaseOrder();
    Resource externalResource = resourceSet.createResource(URI.createFileURI("/com/foo/bar.xml"));
    externalResource.getContents().add(externalObject);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction(resourceSet);

    Supplier supplier = getModel1Factory().createSupplier();
    supplier.getPurchaseOrders().add(externalObject);

    CDOResource resource = transaction.createResource(getResourcePath("/internal"));
    resource.getContents().add(supplier);
    transaction.commit();

    CDORevision salesOrderRevision = CDOUtil.getCDOObject(supplier).cdoRevision();
    Object externalReference = salesOrderRevision.data().get(getModel1Package().getSupplier_PurchaseOrders(), 0);
    assertInstanceOf(CDOIDExternal.class, externalReference);
  }

  public void testWithXMLAndPrefetching() throws Exception
  {
    skipStoreWithoutExternalReferences();

    {
      ResourceSet resourceSet = new ResourceSetImpl();
      Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
      map.put("xml", new XMLResourceFactoryImpl());

      Resource externalResource = resourceSet.createResource(URI.createFileURI("/com/foo/bar.xml"));

      CDOSession session = openSession();
      CDOTransaction transaction = session.openTransaction(resourceSet);

      Supplier supplier = getModel1Factory().createSupplier();

      for (int i = 0; i < 200; i++)
      {
        PurchaseOrder externalObject = getModel1Factory().createPurchaseOrder();
        externalResource.getContents().add(externalObject);

        supplier.getPurchaseOrders().add(externalObject);
      }

      CDOResource resource = transaction.createResource(getResourcePath("/internal"));
      resource.getContents().add(supplier);
      transaction.commit();
    }

    clearCache(getRepository().getRevisionManager());

    {
      ResourceSet resourceSet = new ResourceSetImpl();
      Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
      map.put("xml", new XMLResourceFactoryImpl());

      Resource externalResource = resourceSet.createResource(URI.createFileURI("/com/foo/bar.xml"));
      for (int i = 0; i < 200; i++)
      {
        PurchaseOrder externalObject = getModel1Factory().createPurchaseOrder();
        externalResource.getContents().add(externalObject);
      }

      CDOSession session = openSession();
      ISignalProtocol<?> protocol = ((org.eclipse.emf.cdo.net4j.CDONet4jSession)session).options().getNet4jProtocol();
      SignalCounter signalCounter = new SignalCounter(protocol);

      CDOTransaction transaction = session.openTransaction(resourceSet);
      transaction.options().setRevisionPrefetchingPolicy(CDOUtil.createRevisionPrefetchingPolicy(10));

      CDOResource resource = transaction.getResource(getResourcePath("/internal"));
      Supplier supplier = (Supplier)resource.getContents().get(0);

      for (int i = 0; i < 200; i++)
      {
        PurchaseOrder externalObject = supplier.getPurchaseOrders().get(i);
        System.out.println(externalObject);
      }

      int count = signalCounter.getCountFor(LoadRevisionsRequest.class);
      assertEquals(3, count); // Resource + top folder + top object (supplier)
      protocol.removeListener(signalCounter);

      CDORevisionData data = CDOUtil.getCDOObject(supplier).cdoRevision().data();
      EReference reference = getModel1Package().getSupplier_PurchaseOrders();
      for (int i = 0; i < 200; i++)
      {
        Object value = data.get(reference, i);
        assertInstanceOf(CDOIDExternal.class, value);
      }
    }
  }

  @CleanRepositoriesBefore(reason = "Ref counting")
  public void testXRefExternalObject() throws Exception
  {
    skipStoreWithoutExternalReferences();

    ResourceSet resourceSet = new ResourceSetImpl();
    Map<String, Object> map = resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap();
    map.put("xml", new XMLResourceFactoryImpl());

    PurchaseOrder externalObject = getModel1Factory().createPurchaseOrder();
    Resource externalResource = resourceSet.createResource(URI.createFileURI("/com/foo/bar.xml"));
    externalResource.getContents().add(externalObject);

    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction(resourceSet);

    Supplier supplier = getModel1Factory().createSupplier();
    supplier.getPurchaseOrders().add(externalObject);

    CDOResource resource = transaction.createResource(getResourcePath("/internal"));
    resource.getContents().add(supplier);
    transaction.commit();

    CDOObject wrapper = CDOUtil.wrapExternalObject(externalObject, transaction);
    List<CDOObjectReference> xRefs = transaction.queryXRefs(wrapper);
    assertEquals(1, xRefs.size());
    assertEquals(supplier, xRefs.get(0).getSourceObject());
  }

  private EPackage createDynamicEPackage()
  {
    final EcoreFactory eFactory = EcoreFactory.eINSTANCE;
    final EcorePackage ePackage = EcorePackage.eINSTANCE;

    EClass schoolBookEClass = eFactory.createEClass();
    schoolBookEClass.setName("SchoolBook");

    // create a new attribute for this EClass
    EAttribute level = eFactory.createEAttribute();
    level.setName("level");
    level.setEType(ePackage.getEInt());
    schoolBookEClass.getEStructuralFeatures().add(level);

    // Create a new EPackage and add the new EClasses
    EPackage schoolPackage = createUniquePackage();
    schoolPackage.getEClassifiers().add(schoolBookEClass);
    return schoolPackage;
  }
}
