/*
 * Copyright (c) 2014, 2015 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:
 *    Esteban Dugueperoux - initial API and implementation
 */
package org.eclipse.emf.cdo.tests.bugzilla;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.util.CDOFetchRule;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.internal.net4j.protocol.LoadRevisionsRequest;
import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.Requires;
import org.eclipse.emf.cdo.tests.model1.Category;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
import org.eclipse.emf.cdo.view.CDOView;

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

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.emf.spi.cdo.InternalCDOSession;

import org.junit.Assert;

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

/**
 * Test {@link CDOObject#cdoPrefetch(int)} with branch.
 *
 * @author Esteban Dugueperoux
 */
@Requires(IRepositoryConfig.CAPABILITY_BRANCHING)
@CleanRepositoriesBefore(reason = "to not be disturb by branches created by others tests")
public class Bugzilla_436246_Test extends AbstractCDOTest
{
  private static final String RESOURCE_NAME = "test1.model1";

  private static final String B1_BRANCH_NAME = "b1";

  private static final String B11_BRANCH_NAME = "b11";

  private static final int NB_CATEGORY = 10;

  @Override
  public void setUp() throws Exception
  {
    super.setUp();
    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    CDOResource resource = transaction.createResource(getResourcePath(RESOURCE_NAME));
    Company company = getModel1Factory().createCompany();
    for (int i = 0; i < NB_CATEGORY; i++)
    {
      Category category = getModel1Factory().createCategory();
      company.getCategories().add(category);
    }
    resource.getContents().add(company);
    transaction.commit();
    transaction.close();
    session.close();
  }

  /**
   * Test prefetch on different branches with each having changes.
   */
  public void testCDORevisionPrefetchOnOtherBranchWithChanges() throws Exception
  {
    // Setup
    CDOID companyCDOID = setUpChangesOnBranches();

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

    CDOBranch currentBranch = session.getBranchManager().getMainBranch();
    testCDORevisionFetchWithChangesOnAllBranches(session, currentBranch, signalCounter, companyCDOID, NB_CATEGORY,
        true);

    currentBranch = currentBranch.getBranch(B1_BRANCH_NAME);
    testCDORevisionFetchWithChangesOnAllBranches(session, currentBranch, signalCounter, companyCDOID, 2 * NB_CATEGORY,
        true);

    currentBranch = currentBranch.getBranch(B11_BRANCH_NAME);
    testCDORevisionFetchWithChangesOnAllBranches(session, currentBranch, signalCounter, companyCDOID, 3 * NB_CATEGORY,
        true);

    protocol.removeListener(signalCounter);
  }

  /**
   * Test {@link CDOCollectionLoadingPolicy} on different branches with each having changes.
   */
  public void testCDORevisionCDOFetchRuleOnOtherBranchWithChanges() throws Exception
  {
    // Setup
    CDOID companyCDOID = setUpChangesOnBranches();

    // Test
    CDOSession session = openSession();
    InternalCDOSession internalCDOSession = (InternalCDOSession)session;
    CDOFetchRuleManager fetchRuleManager = new CustomCDOFetchRuleManager(companyCDOID);
    internalCDOSession.setFetchRuleManager(fetchRuleManager);
    ISignalProtocol<?> protocol = ((org.eclipse.emf.cdo.net4j.CDONet4jSession)session).options().getNet4jProtocol();
    SignalCounter signalCounter = new SignalCounter(protocol);

    CDOBranch currentBranch = session.getBranchManager().getMainBranch();
    testCDORevisionFetchWithChangesOnAllBranches(session, currentBranch, signalCounter, companyCDOID, NB_CATEGORY,
        false);

    currentBranch = currentBranch.getBranch(B1_BRANCH_NAME);
    testCDORevisionFetchWithChangesOnAllBranches(session, currentBranch, signalCounter, companyCDOID, 2 * NB_CATEGORY,
        false);

    currentBranch = currentBranch.getBranch(B11_BRANCH_NAME);
    testCDORevisionFetchWithChangesOnAllBranches(session, currentBranch, signalCounter, companyCDOID, 3 * NB_CATEGORY,
        false);

    protocol.removeListener(signalCounter);
  }

  private void testCDORevisionFetchWithChangesOnAllBranches(CDOSession session, CDOBranch currentBranch,
      SignalCounter signalCounter, CDOID companyCDOID, int expectedNbCategories, boolean prefetch)
  {
    CDOView view = session.openView(currentBranch);
    assertEquals(0, signalCounter.getCountFor(LoadRevisionsRequest.class));

    String resourcePath = getResourcePath(RESOURCE_NAME);
    List<String> pathSegments = CDOURIUtil.analyzePath(resourcePath);
    CDOResource resource = view.getResource(resourcePath);
    assertEquals(pathSegments.size(), signalCounter.getCountFor(LoadRevisionsRequest.class));

    if (prefetch)
    {
      resource.cdoPrefetch(CDORevision.DEPTH_INFINITE);
    }
    assertEquals(RESOURCE_NAME, resource.getName());
    EObject eObject = resource.getContents().get(0);
    Assert.assertTrue(eObject instanceof Company);
    Company company = (Company)eObject;
    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));
    Assert.assertEquals(expectedNbCategories, company.getCategories().size());

    view.getRevision(companyCDOID);

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    view.getResourceSet().eAdapters().add(new EContentAdapter());

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    view.close();
    signalCounter.clearCounts();
  }

  private CDOID setUpChangesOnBranches() throws Exception
  {
    CDOSession session = openSession();
    CDOBranch b1Branch = session.getBranchManager().getMainBranch().createBranch(B1_BRANCH_NAME);

    CDOTransaction transaction = session.openTransaction(b1Branch);
    CDOResource resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
    Company company = (Company)resource.getContents().get(0);
    for (int i = 0; i < NB_CATEGORY; i++)
    {
      company.getCategories().add(getModel1Factory().createCategory());
    }
    transaction.commit();
    transaction.close();

    CDOBranch b2Branch = b1Branch.createBranch(B11_BRANCH_NAME);

    transaction = session.openTransaction(b2Branch);
    resource = transaction.getResource(getResourcePath(RESOURCE_NAME));
    company = (Company)resource.getContents().get(0);
    for (int i = 0; i < NB_CATEGORY; i++)
    {
      company.getCategories().add(getModel1Factory().createCategory());
    }
    transaction.commit();
    transaction.close();
    session.close();

    return CDOUtil.getCDOObject(company).cdoID();
  }

  /**
   * Test that after a prefetch of infinite depth of CDORevision on a CDOResource, no more LoadRevisionRequest are sent on the main branch.
   */
  public void testCDORevisionPrefetchOnMainBranch() throws Exception
  {
    CDOSession session = openSession();
    CDOBranch mainBranch = session.getBranchManager().getMainBranch();
    testCDORevisionPrefetchOnBranch(session, mainBranch);
  }

  /**
   * Test that after a prefetch of infinite depth of CDORevision on a CDOResource, no more LoadRevisionRequest are sent on the branch "B1".
   */
  public void testCDORevisionPrefetchOnOtherBranch() throws Exception
  {
    CDOSession session = openSession();
    String newBranchName = "B1";
    CDOBranch newBranch = session.getBranchManager().getMainBranch().createBranch(newBranchName);
    testCDORevisionPrefetchOnBranch(session, newBranch);
  }

  private void testCDORevisionPrefetchOnBranch(CDOSession session, CDOBranch cdoBranch) throws Exception
  {
    CDOTransaction view = session.openTransaction(cdoBranch);
    ISignalProtocol<?> protocol = ((org.eclipse.emf.cdo.net4j.CDONet4jSession)session).options().getNet4jProtocol();
    SignalCounter signalCounter = new SignalCounter(protocol);
    assertEquals(0, signalCounter.getCountFor(LoadRevisionsRequest.class));

    String resourcePath = getResourcePath(RESOURCE_NAME);
    List<String> pathSegments = CDOURIUtil.analyzePath(resourcePath);
    CDOResource resource = view.getResource(resourcePath);
    assertEquals(pathSegments.size(), signalCounter.getCountFor(LoadRevisionsRequest.class));
    resource.cdoPrefetch(CDORevision.DEPTH_INFINITE);

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    Company company = (Company)resource.getContents().get(0);
    CDOID companyCDOID = CDOUtil.getCDOObject(company).cdoID();

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    view.getRevision(companyCDOID);

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    view.getResourceSet().eAdapters().add(new EContentAdapter());

    assertEquals(pathSegments.size() + 1, signalCounter.getCountFor(LoadRevisionsRequest.class));

    protocol.removeListener(signalCounter);
  }

  private class CustomCDOFetchRuleManager implements CDOFetchRuleManager
  {

    private CDOID companyCDOID;

    public CustomCDOFetchRuleManager(CDOID companyCDOID)
    {
      this.companyCDOID = companyCDOID;
    }

    public CDOID getContext()
    {
      return companyCDOID;
    }

    public List<CDOFetchRule> getFetchRules(Collection<CDOID> ids)
    {
      List<CDOFetchRule> fetchRules = null;
      if (ids.contains(companyCDOID))
      {
        CDOFetchRule fetchRule = new CDOFetchRule(getModel1Package().getCompany());
        fetchRule.addFeature(getModel1Package().getCompany_Categories());
        fetchRules = Collections.singletonList(fetchRule);
      }
      return fetchRules;
    }

    public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
    {
      return CDOUtil.createCollectionLoadingPolicy(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }
  }
}
