/*******************************************************************************
 * Copyright (c) 2008-2013 Sonatype, Inc. 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:
 *      Sonatype, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.m2e.internal.discovery;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.equinox.internal.p2.discovery.Catalog;
import org.eclipse.equinox.internal.p2.discovery.DiscoveryCore;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.discovery.model.Tag;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.internal.Workbench;

import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import org.eclipse.m2e.core.internal.lifecyclemapping.LifecycleMappingFactory;
import org.eclipse.m2e.core.internal.lifecyclemapping.model.LifecycleMappingMetadataSource;
import org.eclipse.m2e.core.project.configurator.MojoExecutionKey;
import org.eclipse.m2e.internal.discovery.strategy.M2ERemoteBundleDiscoveryStrategy;
import org.eclipse.m2e.internal.discovery.wizards.MavenCatalogConfiguration;
import org.eclipse.m2e.internal.discovery.wizards.MavenDiscoveryWizard;


@SuppressWarnings("restriction")
public class MavenDiscovery {
  private static final Logger log = LoggerFactory.getLogger(MavenDiscovery.class);

  public static final Tag NO_RESTART_TAG = new Tag("norestart", "norestart"); //$NON-NLS-1$//$NON-NLS-2$

  public static final Tag APPLICABLE_TAG = new Tag("applicable", Messages.MavenDiscovery_Wizard_Applicable_Tag); //$NON-NLS-1$

  private static final Tag EXTRAS_TAG = new Tag("extras", Messages.MavenDiscovery_Wizard_ExtrasTag); //$NON-NLS-1$

  private static final Tag LIFECYCLES_TAG = new Tag("lifecycles", Messages.MavenDiscovery_Wizard_LifecyclesTag); //$NON-NLS-1$

  private static final Tag MAVEN_TAG = new Tag("maven", Messages.MavenDiscovery_Wizard_MavenTag); //$NON-NLS-1$

  private static final String DEFAULT_BASEURL = "http://download.eclipse.org/technology/m2e/discovery/"; //$NON-NLS-1$

  private static final String DEFAULT_FILENAME = "directory-1.10.xml"; //$NON-NLS-1$

  public static final String DEFAULT_URL = DEFAULT_BASEURL + DEFAULT_FILENAME;

  private static final String CONFIGURED_URL = System.getProperty("m2e.discovery.url"); //$NON-NLS-1$

  private static final String BASEURL = System.getProperty("m2e.discovery.baseurl", DEFAULT_BASEURL); //$NON-NLS-1$

  public static final String PATH;

  public static final String LIFECYCLE_PATH = "lifecycle/"; //$NON-NLS-1$

  public static final String LIFECYCLE_EXT = ".xml"; //$NON-NLS-1$

  public static final String PLUGINXML_EXT = ".pluginxml"; //$NON-NLS-1$

  static {
    PATH = CONFIGURED_URL != null ? CONFIGURED_URL : BASEURL + DEFAULT_FILENAME;
  }

  @SuppressWarnings("unchecked")
  public static void launchWizard(Shell shell) {
    launchWizard(shell, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
  }

  public static void launchWizard(final Collection<String> packagingTypes, final Collection<MojoExecutionKey> mojos,
      final Collection<String> lifecycleIds, final Collection<String> configuratorIds) {
    final Display display = Workbench.getInstance().getDisplay();
    display.asyncExec(new Runnable() {
      public void run() {
        launchWizard(display.getActiveShell(), packagingTypes, mojos, lifecycleIds, configuratorIds);
      }
    });
  }

  public static void launchWizard(Shell shell, Collection<String> packagingTypes, Collection<MojoExecutionKey> mojos,
      Collection<String> lifecycleIds, Collection<String> configuratorIds) {
    Catalog catalog = getCatalog();

    // Build the list of tags to show in the Wizard header
    List<Tag> tags = new ArrayList<Tag>(3);
    if(!packagingTypes.isEmpty() || !mojos.isEmpty() || !configuratorIds.isEmpty() || !lifecycleIds.isEmpty()) {
      tags.add(APPLICABLE_TAG);
    }
    tags.add(EXTRAS_TAG);
    tags.add(LIFECYCLES_TAG);
    tags.add(MAVEN_TAG);
    catalog.setTags(tags);

    // Create configuration for the catalog
    MavenCatalogConfiguration configuration = new MavenCatalogConfiguration();
    configuration.setShowTagFilter(true);
    if(!packagingTypes.isEmpty() || !mojos.isEmpty() || !configuratorIds.isEmpty() || !lifecycleIds.isEmpty()) {
      tags = new ArrayList<Tag>(1);
      tags.add(APPLICABLE_TAG);
      configuration.setSelectedTags(tags);
    } else {
      configuration.setSelectedTags(tags);
    }
    configuration.setShowInstalledFilter(false);
    configuration.setSelectedPackagingTypes(packagingTypes);
    configuration.setSelectedMojos(mojos);
    configuration.setSelectedLifecycleIds(lifecycleIds);
    configuration.setSelectedConfigurators(configuratorIds);

    MavenDiscoveryWizard wizard = new MavenDiscoveryWizard(catalog, configuration);
    WizardDialog dialog = new WizardDialog(shell, wizard);
    dialog.open();
  }

  public static Catalog getCatalog() {
    Catalog catalog = new Catalog();
    catalog.setEnvironment(DiscoveryCore.createEnvironment());
    catalog.setVerifyUpdateSiteAvailability(false);

    // look for remote descriptor
    M2ERemoteBundleDiscoveryStrategy remoteDiscoveryStrategy = new M2ERemoteBundleDiscoveryStrategy();
    remoteDiscoveryStrategy.setDirectoryUrl(PATH);
    catalog.getDiscoveryStrategies().add(remoteDiscoveryStrategy);
    return catalog;
  }

  public static LifecycleMappingMetadataSource getLifecycleMappingMetadataSource(CatalogItem ci) {
    URL url = null;
    try {
      url = getLifecycleMappingMetadataSourceURL(ci);
      if(url == null) {
        return null;
      }
      // To ensure we can delete the temporary file we need to prevent caching, see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4386865
      URLConnection conn = url.openConnection();
      if(conn instanceof JarURLConnection) {
        ((JarURLConnection) conn).setDefaultUseCaches(false);
      }
      InputStream is = conn.getInputStream();
      try {
        return LifecycleMappingFactory.createLifecycleMappingMetadataSource(is);
      } finally {
        IOUtil.close(is);
      }
    } catch(FileNotFoundException e) {
      // CatalogItem does not contain lifecycle mapping
      log.info("No lifecyle mapping found at " + url);
    } catch(Exception e) {
      log.warn(NLS.bind(Messages.MavenCatalogViewer_Error_loading_lifecycle, ci.getId()), e);
    }
    return null;
  }

  /*
   * Restart is required when one or more CatalogItem lacks the norestart tag.
   */
  public static boolean requireRestart(Iterable<CatalogItem> catalogItems) {
    for(CatalogItem item : catalogItems) {
      if(!item.hasTag(NO_RESTART_TAG)) {
        return true;
      }
    }
    return false;
  }

  public static void getProvidedProjectConfigurators(CatalogItem ci, List<String> projectConfigurators,
      List<String> mappingStrategies) {
    try {
      URL url = ci.getSource().getResource(LIFECYCLE_PATH + ci.getId() + PLUGINXML_EXT);
      if(url != null) {
        InputStream is = url.openStream();
        parsePluginXml(is, projectConfigurators, mappingStrategies);
      }
    } catch(FileNotFoundException e) {
      log.warn("CatalogItem {} does not contain lifecycle mapping metadata", ci.getId()); //$NON-NLS-1$
    } catch(Exception e) {
      log.warn(NLS.bind(Messages.MavenCatalogViewer_Error_loading_lifecycle, ci.getId()), e);
    }
  }

  public static void parsePluginXml(InputStream is, List<String> configurators, List<String> mappingStrategies)
      throws XmlPullParserException, IOException {
    Xpp3Dom plugin = Xpp3DomBuilder.build(is, "UTF-8"); //$NON-NLS-1$
    Xpp3Dom[] extensions = plugin.getChildren("extension"); //$NON-NLS-1$
    for(Xpp3Dom extension : extensions) {
      String extensionPoint = extension.getAttribute("point"); //$NON-NLS-1$
      if(LifecycleMappingFactory.EXTENSION_PROJECT_CONFIGURATORS.equals(extensionPoint)) {
        Xpp3Dom[] configuratorsDom = extension.getChildren("configurator"); //$NON-NLS-1$
        for(Xpp3Dom configurator : configuratorsDom) {
          String id = configurator.getAttribute("id"); //$NON-NLS-1$
          if(id != null) {
            configurators.add(id);
          }
        }
      } else if(LifecycleMappingFactory.EXTENSION_LIFECYCLE_MAPPINGS.equals(extensionPoint)) {
        Xpp3Dom[] lifecycleMappingsDom = extension.getChildren("lifecycleMapping"); //$NON-NLS-1$
        for(Xpp3Dom lifecycleMapping : lifecycleMappingsDom) {
          String id = lifecycleMapping.getAttribute("id"); //$NON-NLS-1$
          if(id != null) {
            mappingStrategies.add(id);
          }
        }
      }
    }
  }

  public static URL getLifecycleMappingMetadataSourceURL(CatalogItem ci) {
    return ci.getSource().getResource(LIFECYCLE_PATH + ci.getId() + LIFECYCLE_EXT);
  }
}
