package org.eclipse.scout.sdk.compatibility.v38v42.internal.service;

import java.net.URI;
import java.text.MessageFormat;
import java.util.Iterator;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.IProvisioningAgentProvider;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.scout.sdk.compatibility.internal.ScoutCompatibilityActivator;
import org.eclipse.scout.sdk.compatibility.internal.service.IP2CompatService;

public class P2CompatService implements IP2CompatService {
  @Override
  public String getLatestVersion(String rootIU, URI p2RepositoryURI, IProgressMonitor monitor) throws CoreException {
    String[] latestVersions = getLatestVersions(new String[]{rootIU}, p2RepositoryURI, monitor);
    if (latestVersions != null && latestVersions.length > 0) {
      return latestVersions[0];
    }
    return null;
  }

  private String[] getLatestVersions(String[] rootIUs, URI p2RepositoryURI, IProgressMonitor monitor) throws CoreException {
    IProvisioningAgent agent = getAgent();
    IMetadataRepositoryManager repoManager = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
    IMetadataRepository metadataRepository = loadRepository(p2RepositoryURI, repoManager, monitor);
    String[] result = selectLatestVersions(rootIUs, metadataRepository);
    return result;
  }

  private IProvisioningAgent getAgent() throws CoreException {
    IPath stateLocation = ScoutCompatibilityActivator.getDefault().getStateLocation();
    URI stateLocationURI = stateLocation.toFile().toURI();
    IProvisioningAgentProvider agentProvider = (IProvisioningAgentProvider) ScoutCompatibilityActivator.getDefault().acquireService(IProvisioningAgentProvider.SERVICE_NAME);
    if (agentProvider == null) {
      IStatus status = new Status(IStatus.ERROR, ScoutCompatibilityActivator.PLUGIN_ID, "Agent provider service not available");
      throw new CoreException(status);
    }
    return agentProvider.createAgent(stateLocationURI);
  }

  private IMetadataRepository loadRepository(final URI p2RepositoryURI, final IMetadataRepositoryManager repoManager, final IProgressMonitor monitor) throws CoreException {
    IMetadataRepository result;
    SubMonitor subMonitor = SubMonitor.convert(monitor);
    try {
      SubMonitor repositoryMonitor = subMonitor.newChild(1);
      result = repoManager.loadRepository(p2RepositoryURI, repositoryMonitor);
    }
    catch (ProvisionException e) {
      String message = "Failed to load repository <{0}>"; //$NON-NLS-1$
      Object[] arguments = new Object[]{p2RepositoryURI};
      String fmtMessage = MessageFormat.format(message, arguments);
      IStatus status = new Status(IStatus.ERROR, ScoutCompatibilityActivator.PLUGIN_ID, fmtMessage, e);
      throw new CoreException(status);
    }
    return result;
  }

  private static String[] selectLatestVersions(final String[] rootIUs, final IMetadataRepository metadataRepository) throws CoreException {
    String[] result = new String[rootIUs.length];
    for (int i = 0; i < rootIUs.length; i++) {
      String rootIuId = rootIUs[i];
      IQuery<IInstallableUnit> latestQuery = QueryUtil.createLatestQuery(QueryUtil.createIUQuery(rootIuId));
      IQueryResult<IInstallableUnit> queryResult = metadataRepository.query(latestQuery, new NullProgressMonitor());
      if (queryResult.isEmpty()) {
        String messag = "Feature <{0}> not found"; //$NON-NLS-1$
        Object[] arguments = new Object[]{
            rootIuId
        };
        String fmtMessage = MessageFormat.format(messag, arguments);
        IStatus status = new Status(IStatus.ERROR, ScoutCompatibilityActivator.PLUGIN_ID, fmtMessage);
        throw new CoreException(status);
      }
      Iterator<IInstallableUnit> iterator = queryResult.iterator();
      IInstallableUnit iu = iterator.next();

      result[i] = iu.getVersion().toString();
    }
    return result;
  }
}
