/*
 * Copyright (c) 2014-2016 Eike Stepper (Loehne, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.oomph.p2.internal.core;

import org.eclipse.oomph.p2.ProfileDefinition;
import org.eclipse.oomph.p2.Repository;
import org.eclipse.oomph.p2.core.Agent;
import org.eclipse.oomph.p2.core.BundlePool;
import org.eclipse.oomph.p2.core.P2Util;
import org.eclipse.oomph.p2.core.Profile;
import org.eclipse.oomph.util.IORuntimeException;
import org.eclipse.oomph.util.IOUtil;
import org.eclipse.oomph.util.SubMonitor;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.IRepositoryManager;
import org.eclipse.equinox.p2.repository.artifact.ArtifactKeyQuery;
import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @author Eike Stepper
 */
public final class AgentAnalyzer
{
  private final Agent agent;

  private final Map<File, AnalyzedBundlePool> bundlePools = new HashMap<File, AnalyzedBundlePool>();

  private final CountDownLatch analyzeLatch;

  private final List<Job> analyzeProfileJobs = new ArrayList<Job>();

  private Set<URI> repositoryURIs;

  private Handler handler;

  public AgentAnalyzer(Agent agent, boolean analyzeDamage, Handler handler, IProgressMonitor monitor)
  {
    this.agent = agent;
    this.handler = handler;

    Collection<Profile> allProfiles = agent.getAllProfiles();
    monitor.beginTask("Loading profiles...", allProfiles.size());

    try
    {
      for (Profile p2Profile : allProfiles)
      {
        P2CorePlugin.checkCancelation(monitor);
        if (p2Profile.isValid())
        {
          monitor.subTask(p2Profile.getProfileId());

          BundlePool p2BundlePool = p2Profile.getBundlePool();
          if (p2BundlePool != null)
          {
            File installFolder = p2Profile.getInstallFolder();
            File location = p2BundlePool.getLocation();
            if (!location.equals(installFolder))
            {
              AnalyzedBundlePool bundlePool = bundlePools.get(location);
              if (bundlePool == null)
              {
                bundlePool = new AnalyzedBundlePool(this, location);
                bundlePools.put(location, bundlePool);
              }

              bundlePool.addProfile(p2Profile, installFolder);
            }
          }
        }

        monitor.worked(1);
      }
    }
    finally
    {
      monitor.done();
    }

    if (handler != null)
    {
      handler.analyzerChanged(this);
    }

    analyzeLatch = new CountDownLatch(bundlePools.size());

    for (AnalyzedBundlePool bundlePool : bundlePools.values())
    {
      Job job = bundlePool.analyze(analyzeLatch, analyzeDamage);
      analyzeProfileJobs.add(job);
    }
  }

  public void awaitAnalyzing(IProgressMonitor monitor)
  {
    int totalWork = bundlePools.size();
    SubMonitor progress = SubMonitor.convert(monitor, "Analyzing...", totalWork).detectCancelation();
    progress.subTask("Analyzing artifacts...");

    int work = totalWork - (int)analyzeLatch.getCount();
    if (work != 0)
    {
      progress.worked(work);
    }

    try
    {
      while (!analyzeLatch.await(100, TimeUnit.MILLISECONDS))
      {
        P2CorePlugin.checkCancelation(monitor);

        int newWork = totalWork - (int)analyzeLatch.getCount();
        if (newWork != work)
        {
          progress.worked(newWork - work);
          work = newWork;
        }
      }
    }
    catch (InterruptedException ex)
    {
      //$FALL-THROUGH$
    }
    finally
    {
      progress.done();
    }
  }

  public void dispose()
  {
    handler = null;

    for (Job job : analyzeProfileJobs)
    {
      job.cancel();
    }

    analyzeProfileJobs.clear();
    bundlePools.clear();
  }

  public Map<File, AnalyzedBundlePool> getBundlePools()
  {
    return bundlePools;
  }

  public Set<URI> getRepositoryURIs()
  {
    if (repositoryURIs == null)
    {
      repositoryURIs = new HashSet<URI>();

      IArtifactRepositoryManager repositoryManager = agent.getArtifactRepositoryManager();
      // addURIs(repositoryURIs, repositoryManager, IRepositoryManager.REPOSITORIES_ALL);
      // addURIs(repositoryURIs, repositoryManager, IRepositoryManager.REPOSITORIES_DISABLED);
      // addURIs(repositoryURIs, repositoryManager, IRepositoryManager.REPOSITORIES_LOCAL);
      // addURIs(repositoryURIs, repositoryManager, IRepositoryManager.REPOSITORIES_NON_LOCAL);
      // addURIs(repositoryURIs, repositoryManager, IRepositoryManager.REPOSITORIES_SYSTEM);
      addURIs(repositoryURIs, repositoryManager, IRepositoryManager.REPOSITORIES_NON_SYSTEM);

      for (AnalyzedBundlePool bundlePool : bundlePools.values())
      {
        // Don't use possibly damaged local bundle pools for damage repair
        repositoryURIs.remove(bundlePool.getLocation().toURI());
      }
    }

    return repositoryURIs;
  }

  private void analyzerChanged(AgentAnalyzer analyzer)
  {
    if (handler != null)
    {
      handler.analyzerChanged(analyzer);
    }
  }

  private void bundlePoolChanged(AnalyzedBundlePool bundlePool, boolean artifacts, boolean profiles)
  {
    if (handler != null)
    {
      handler.bundlePoolChanged(bundlePool, artifacts, profiles);
    }
  }

  private void profileChanged(AnalyzedProfile profile)
  {
    if (handler != null)
    {
      handler.profileChanged(profile);
    }
  }

  private void artifactChanged(AnalyzedArtifact artifact)
  {
    if (handler != null)
    {
      handler.artifactChanged(artifact);
    }
  }

  private void addURIs(Set<URI> repos, IArtifactRepositoryManager repositoryManager, int flag)
  {
    for (URI uri : repositoryManager.getKnownRepositories(flag))
    {
      repos.add(uri);
    }
  }

  /**
   * @author Eike Stepper
   */
  public interface Handler
  {
    public void analyzerChanged(AgentAnalyzer analyzer);

    public void bundlePoolChanged(AnalyzedBundlePool bundlePool, boolean artifacts, boolean profiles);

    public void profileChanged(AnalyzedProfile profile);

    public void artifactChanged(AnalyzedArtifact artifact);
  }

  /**
   * @author Eike Stepper
   */
  public static final class AnalyzedBundlePool implements Comparable<AnalyzedBundlePool>
  {
    private final AgentAnalyzer analyzer;

    private final File location;

    private final Set<URI> repositoryURIs = new LinkedHashSet<URI>();

    private final List<AnalyzedProfile> profiles = new ArrayList<AnalyzedProfile>();

    private final Map<IArtifactKey, AnalyzedArtifact> artifacts = new HashMap<IArtifactKey, AnalyzedArtifact>();

    private final Set<AnalyzedArtifact> unusedArtifacts = new HashSet<AnalyzedArtifact>();

    private final Set<AnalyzedArtifact> damagedArtifacts = new HashSet<AnalyzedArtifact>();

    private int damagedArtifactsPercent;

    private AnalyzedArtifact[] artifactsArray;

    private AnalyzedArtifact[] unusedArtifactsArray;

    private AnalyzedArtifact[] damagedArtifactsArray;

    private IFileArtifactRepository p2BundlePool;

    private boolean analyzing = true;

    private boolean analyzingDamage = true;

    public AnalyzedBundlePool(AgentAnalyzer analyzer, File location)
    {
      this.analyzer = analyzer;
      this.location = location;
    }

    public boolean isAnalyzing()
    {
      return analyzing;
    }

    public AgentAnalyzer getAnalyzer()
    {
      return analyzer;
    }

    public File getLocation()
    {
      return location;
    }

    public Set<URI> getRepositoryURIs()
    {
      return repositoryURIs;
    }

    public int getProfilesCount()
    {
      synchronized (this)
      {
        return profiles.size();
      }
    }

    public AnalyzedProfile[] getProfiles()
    {
      synchronized (this)
      {
        return profiles.toArray(new AnalyzedProfile[profiles.size()]);
      }
    }

    public AnalyzedProfile[] getUnusedProfiles()
    {
      List<AnalyzedProfile> unusedProfiles = new ArrayList<AnalyzedProfile>();

      synchronized (this)
      {
        for (AnalyzedProfile profile : profiles)
        {
          if (profile.isUnused())
          {
            unusedProfiles.add(profile);
          }
        }
      }

      return unusedProfiles.toArray(new AnalyzedProfile[unusedProfiles.size()]);
    }

    public int getUnusedProfilesCount()
    {
      int count = 0;

      synchronized (this)
      {
        for (AnalyzedProfile profile : profiles)
        {
          if (profile.isUnused())
          {
            ++count;
          }
        }
      }

      return count;
    }

    public int getArtifactCount()
    {
      synchronized (this)
      {
        return artifacts.size();
      }
    }

    public AnalyzedArtifact[] getArtifacts()
    {
      synchronized (this)
      {
        if (artifactsArray == null)
        {
          artifactsArray = artifacts.values().toArray(new AnalyzedArtifact[artifacts.size()]);
          Arrays.sort(artifactsArray);
        }

        return artifactsArray;
      }
    }

    public AnalyzedArtifact getArtifact(IArtifactKey key)
    {
      synchronized (this)
      {
        return artifacts.get(key);
      }
    }

    public int getUnusedArtifactsCount()
    {
      synchronized (this)
      {
        return unusedArtifacts.size();
      }
    }

    public AnalyzedArtifact[] getUnusedArtifacts()
    {
      synchronized (this)
      {
        if (unusedArtifactsArray == null)
        {
          unusedArtifactsArray = unusedArtifacts.toArray(new AnalyzedArtifact[unusedArtifacts.size()]);
          Arrays.sort(unusedArtifactsArray);
        }

        return unusedArtifactsArray;
      }
    }

    public int getDamagedArtifactsPercent()
    {
      return damagedArtifactsPercent;
    }

    public int getDamagedArtifactsCount()
    {
      synchronized (damagedArtifacts)
      {
        return damagedArtifacts.size();
      }
    }

    public AnalyzedArtifact[] getDamagedArtifacts()
    {
      synchronized (this)
      {
        if (damagedArtifactsArray == null)
        {
          damagedArtifactsArray = damagedArtifacts.toArray(new AnalyzedArtifact[damagedArtifacts.size()]);
          Arrays.sort(damagedArtifactsArray);
        }

        return damagedArtifactsArray;
      }
    }

    public boolean isAnalyzingDamage()
    {
      return analyzingDamage;
    }

    public int compareTo(AnalyzedBundlePool o)
    {
      return location.getAbsolutePath().compareTo(o.getLocation().getAbsolutePath());
    }

    @Override
    public String toString()
    {
      return location.toString();
    }

    synchronized IFileArtifactRepository getP2BundlePool(IProgressMonitor monitor)
    {
      if (p2BundlePool == null)
      {
        try
        {
          IArtifactRepositoryManager repositoryManager = analyzer.agent.getArtifactRepositoryManager();
          p2BundlePool = (IFileArtifactRepository)repositoryManager.loadRepository(location.toURI(), monitor);
        }
        catch (ProvisionException ex)
        {
          throw new IllegalStateException(ex);
        }
      }

      return p2BundlePool;
    }

    AnalyzedProfile addProfile(Profile p2Profile, File installFolder)
    {
      AnalyzedProfile profile = new AnalyzedProfile(this, p2Profile, installFolder);
      repositoryURIs.addAll(profile.getRepositoryURIs());

      synchronized (this)
      {
        profiles.add(profile);
        Collections.sort(profiles);
      }

      return profile;
    }

    Job analyze(final CountDownLatch analyzeLatch, final boolean analyzeDamage)
    {
      Job job = new Job("Analyzing bundle pool " + location)
      {
        @Override
        protected IStatus run(IProgressMonitor monitor)
        {
          analyze(analyzeDamage, monitor);
          analyzeLatch.countDown();
          return Status.OK_STATUS;
        }
      };

      job.schedule();
      return job;
    }

    private void analyze(boolean analyzeDamage, IProgressMonitor monitor)
    {
      Random random = new Random(System.currentTimeMillis());

      IFileArtifactRepository p2BundlePool = getP2BundlePool(monitor);
      for (IArtifactKey key : P2Util.asIterable(p2BundlePool.query(ArtifactKeyQuery.ALL_KEYS, monitor)))
      {
        P2CorePlugin.checkCancelation(monitor);

        File file = p2BundlePool.getArtifactFile(key);
        AnalyzedArtifact artifact = new AnalyzedArtifact(this, key, file);

        synchronized (this)
        {
          artifacts.put(key, artifact);
          artifactsArray = null;
        }

        if (random.nextInt(100) < 2)
        {
          analyzer.bundlePoolChanged(this, false, false);
        }
      }

      analyzer.bundlePoolChanged(this, true, false);

      for (AnalyzedProfile profile : getProfiles())
      {
        P2CorePlugin.checkCancelation(monitor);
        profile.analyze(monitor);
      }

      analyzer.analyzerChanged(analyzer);

      analyzeUnusedArtifacts(monitor);
      analyzing = false;

      if (analyzeDamage)
      {
        analyzeDamagedArtifacts(monitor);
      }
    }

    private void analyzeUnusedArtifacts(IProgressMonitor monitor)
    {
      for (AnalyzedArtifact artifact : getArtifacts())
      {
        P2CorePlugin.checkCancelation(monitor);
        if (analyzeUnusedArtifact(artifact, monitor))
        {
          synchronized (this)
          {
            unusedArtifacts.add(artifact);
            unusedArtifactsArray = null;
          }

          analyzer.bundlePoolChanged(this, false, false);
        }
      }

      analyzer.bundlePoolChanged(this, true, false);
    }

    private boolean analyzeUnusedArtifact(AnalyzedArtifact artifact, IProgressMonitor monitor)
    {
      for (AnalyzedProfile profile : getProfiles())
      {
        P2CorePlugin.checkCancelation(monitor);
        if (profile.getArtifacts().contains(artifact))
        {
          return false;
        }
      }

      return true;
    }

    private void analyzeDamagedArtifacts(IProgressMonitor monitor)
    {
      AnalyzedArtifact[] artifacts = getArtifacts();
      int total = artifacts.length;
      int i = 0;

      for (AnalyzedArtifact artifact : artifacts)
      {
        P2CorePlugin.checkCancelation(monitor);

        int percent = ++i * 100 / total;
        if (percent != damagedArtifactsPercent)
        {
          damagedArtifactsPercent = percent;
          analyzer.bundlePoolChanged(this, false, false);
        }

        synchronized (artifact)
        {
          IArtifactKey key = artifact.getKey();
          if (getArtifact(key) == null)
          {
            // Continue with next artifact if this artifact was deleted meanwhile
            continue;
          }
        }

        monitor.subTask("Validating " + artifact);
        if (isDamaged(artifact))
        {
          synchronized (this)
          {
            damagedArtifacts.add(artifact);
            damagedArtifactsArray = null;
          }

          analyzer.bundlePoolChanged(this, false, false);

          artifact.setDamaged();
          analyzer.artifactChanged(artifact);
        }
      }

      analyzer.bundlePoolChanged(this, false, false);
      analyzingDamage = false;
    }

    @SuppressWarnings("restriction")
    private static boolean isDamaged(AnalyzedArtifact artifact)
    {
      File file = artifact.getFile();
      if (file == null || !file.exists())
      {
        return true;
      }

      if (file.isFile())
      {
        ZipFile zipFile = null;

        try
        {
          zipFile = new ZipFile(file);
          Enumeration<? extends ZipEntry> entries = zipFile.entries();
          if (!entries.hasMoreElements())
          {
            return true;
          }

          do
          {
            ZipEntry entry = entries.nextElement();

            entry.getName();
            entry.getCompressedSize();
            entry.getCrc();

            InputStream inputStream = null;

            try
            {
              inputStream = zipFile.getInputStream(entry);
              if (inputStream == null)
              {
                return true;
              }
            }
            finally
            {
              IOUtil.close(inputStream);
            }
          } while (entries.hasMoreElements());
        }
        catch (Exception ex)
        {
          return true;
        }
        finally
        {
          try
          {
            if (zipFile != null)
            {
              zipFile.close();
            }
          }
          catch (IOException ex)
          {
            throw new IORuntimeException(ex);
          }
        }
      }

      try
      {
        String type = artifact.getType();
        org.eclipse.equinox.p2.publisher.AbstractPublisherAction action;
        String namespace;
        if (AnalyzedArtifact.TYPE_FEATURE.equals(type))
        {
          action = new org.eclipse.equinox.p2.publisher.eclipse.FeaturesAction(new File[] { file });
          namespace = "org.eclipse.update.feature";
        }
        else if (AnalyzedArtifact.TYPE_PLUGIN.equals(type))
        {
          action = new org.eclipse.equinox.p2.publisher.eclipse.BundlesAction(new File[] { file });
          namespace = "osgi.bundle";
        }
        else
        {
          return false;
        }

        org.eclipse.equinox.p2.publisher.PublisherInfo info = new org.eclipse.equinox.p2.publisher.PublisherInfo();
        org.eclipse.equinox.p2.publisher.PublisherResult result = new org.eclipse.equinox.p2.publisher.PublisherResult();
        action.perform(info, result, new NullProgressMonitor());
        IArtifactKey key = artifact.getKey();
        String id = key.getId();
        Version version = key.getVersion();
        for (Iterator<IInstallableUnit> it = result.everything(); it.hasNext();)
        {
          IInstallableUnit iu = it.next();
          for (IProvidedCapability capability : iu.getProvidedCapabilities())
          {
            String name = capability.getName();
            String capabilityNamespace = capability.getNamespace();
            Version capabilityVersion = capability.getVersion();
            if (namespace.equals(capabilityNamespace) && id.equals(name) && version.equals(capabilityVersion))
            {
              return false;
            }
          }
        }
      }
      catch (Exception exception)
      {
        return true;
      }

      return true;
    }
  }

  /**
   * @author Eike Stepper
   */
  public static final class AnalyzedProfile implements Comparable<AnalyzedProfile>
  {
    public static final String ECLIPSE = "Eclipse";

    public static final String TARGLET = "Targlet";

    public static final String UNKNOWN = "Unknown";

    @Deprecated
    private static final String PROP_TARGLET_CONTAINER_ID = "targlet.container.id";

    private final AnalyzedBundlePool bundlePool;

    private final Profile p2Profile;

    private final File installFolder;

    private final String type;

    private final int roots;

    private final Set<URI> repositoryURIs = new LinkedHashSet<URI>();

    private final Set<AnalyzedArtifact> artifacts = new HashSet<AnalyzedArtifact>();

    private final Set<AnalyzedArtifact> damagedArtifacts = new HashSet<AnalyzedArtifact>();

    private AnalyzedArtifact[] damagedArtifactsArray;

    public AnalyzedProfile(AnalyzedBundlePool bundlePool, Profile p2Profile, File installFolder)
    {
      this.bundlePool = bundlePool;
      this.p2Profile = p2Profile;
      this.installFolder = installFolder;

      if (p2Profile.getProperty(PROP_TARGLET_CONTAINER_ID) != null)
      {
        type = TARGLET;
      }
      else if (installFolder != null)
      {
        type = ECLIPSE;
      }
      else
      {
        type = UNKNOWN;
      }

      ProfileDefinition profileDefinition = p2Profile.getDefinition();
      roots = profileDefinition.getRequirements().size();

      for (Repository repository : profileDefinition.getRepositories())
      {
        try
        {
          repositoryURIs.add(new URI(repository.getURL()));
        }
        catch (URISyntaxException ex)
        {
          P2CorePlugin.INSTANCE.log(ex);
        }
      }
    }

    public AnalyzedBundlePool getBundlePool()
    {
      return bundlePool;
    }

    public Profile getP2Profile()
    {
      return p2Profile;
    }

    public boolean isUnused()
    {
      return !p2Profile.isUsed();
    }

    public String getID()
    {
      return p2Profile.getProfileId();
    }

    public File getInstallFolder()
    {
      return installFolder;
    }

    public String getType()
    {
      return type;
    }

    public final int getRoots()
    {
      return roots;
    }

    public Set<URI> getRepositoryURIs()
    {
      return repositoryURIs;
    }

    public Set<AnalyzedArtifact> getArtifacts()
    {
      return artifacts;
    }

    public boolean isDamaged()
    {
      synchronized (bundlePool)
      {
        return !damagedArtifacts.isEmpty();
      }
    }

    public int getDamagedArtifactsCount()
    {
      synchronized (bundlePool)
      {
        return damagedArtifacts.size();
      }
    }

    public AnalyzedArtifact[] getDamagedArtifacts()
    {
      synchronized (bundlePool)
      {
        if (damagedArtifactsArray == null)
        {
          damagedArtifactsArray = damagedArtifacts.toArray(new AnalyzedArtifact[damagedArtifacts.size()]);
          Arrays.sort(damagedArtifactsArray);
        }

        return damagedArtifactsArray;
      }
    }

    public int compareTo(AnalyzedProfile o)
    {
      return getID().compareTo(o.getID());
    }

    @Override
    public String toString()
    {
      return getID();
    }

    void analyze(IProgressMonitor monitor)
    {
      for (IInstallableUnit iu : P2Util.asIterable(p2Profile.query(QueryUtil.createIUAnyQuery(), monitor)))
      {
        for (IArtifactKey key : iu.getArtifacts())
        {
          AnalyzedArtifact artifact = bundlePool.getArtifact(key);
          if (artifact != null)
          {
            synchronized (bundlePool)
            {
              artifacts.add(artifact);
              artifact.addProfile(this);
            }

            bundlePool.analyzer.profileChanged(this);
          }
        }
      }
    }

    public synchronized void delete(IProgressMonitor monitor)
    {
      if (isUnused())
      {
        monitor.subTask("Deleting " + this);
        p2Profile.delete();

        boolean artifactsChanged = false;
        synchronized (bundlePool)
        {
          for (AnalyzedArtifact artifact : artifacts)
          {
            if (artifact.profiles.remove(this))
            {
              artifactsChanged = true;

              if (artifact.profiles.isEmpty())
              {
                bundlePool.unusedArtifacts.add(artifact);
                bundlePool.unusedArtifactsArray = null;
              }
            }
          }

          bundlePool.profiles.remove(this);
        }

        bundlePool.analyzer.bundlePoolChanged(bundlePool, true, true);
        bundlePool.analyzer.profileChanged(this);

        if (artifactsChanged)
        {
          bundlePool.analyzer.artifactChanged(null);
        }
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  public static final class AnalyzedArtifact implements Comparable<AnalyzedArtifact>
  {
    public static final String REPAIR_TASK_NAME = "Repairing artifacts";

    public static final String TYPE_FEATURE = "Feature";

    public static final String TYPE_PLUGIN = "Plugin";

    public static final String TYPE_BINARY = "Binary";

    private final AnalyzedBundlePool bundlePool;

    private final IArtifactKey key;

    private final String type;

    private final File file;

    private final List<AnalyzedProfile> profiles = new ArrayList<AnalyzedProfile>();

    private boolean damaged;

    public AnalyzedArtifact(AnalyzedBundlePool bundlePool, IArtifactKey key, File file)
    {
      this.bundlePool = bundlePool;
      this.key = key;
      this.file = file;

      String classifier = key.getClassifier();
      if ("org.eclipse.update.feature".equals(classifier))
      {
        type = TYPE_FEATURE;
      }
      else if ("osgi.bundle".equals(classifier))
      {
        type = TYPE_PLUGIN;
      }
      else
      {
        type = TYPE_BINARY;
      }
    }

    public boolean isUnused()
    {
      return profiles.isEmpty();
    }

    public boolean isDamaged()
    {
      return damaged;
    }

    public AnalyzedBundlePool getBundlePool()
    {
      return bundlePool;
    }

    public IArtifactKey getKey()
    {
      return key;
    }

    public String getType()
    {
      return type;
    }

    public String getID()
    {
      return key.getId();
    }

    public String getVersion()
    {
      return key.getVersion().toString();
    }

    public File getFile()
    {
      return file;
    }

    public List<AnalyzedProfile> getProfiles()
    {
      return profiles;
    }

    public int compareTo(AnalyzedArtifact o)
    {
      int result = key.getId().compareTo(o.key.getId());
      if (result == 0)
      {
        result = key.getVersion().compareTo(o.key.getVersion());
        if (result == 0)
        {
          result = type.compareTo(o.type);
        }
      }

      return result;
    }

    @Override
    public int hashCode()
    {
      final int prime = 31;
      int result = 1;
      result = prime * result + (key == null ? 0 : key.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj)
    {
      if (this == obj)
      {
        return true;
      }

      if (obj == null)
      {
        return false;
      }

      if (getClass() != obj.getClass())
      {
        return false;
      }

      AnalyzedArtifact other = (AnalyzedArtifact)obj;
      if (key == null)
      {
        if (other.key != null)
        {
          return false;
        }
      }
      else if (!key.equals(other.key))
      {
        return false;
      }

      return true;
    }

    @Override
    public String toString()
    {
      return key.getId() + " " + key.getVersion();
    }

    void addProfile(AnalyzedProfile profile)
    {
      profiles.add(profile);
    }

    void setDamaged()
    {
      damaged = true;
      for (AnalyzedProfile profile : profiles)
      {
        synchronized (bundlePool)
        {
          profile.damagedArtifacts.add(this);
          profile.damagedArtifactsArray = null;
        }

        bundlePool.analyzer.handler.profileChanged(profile);
      }
    }

    public synchronized void delete(IProgressMonitor monitor)
    {
      if (isUnused())
      {
        deleteUnused(monitor);
      }
      else
      {
        monitor.subTask("Deleting " + this);
        IOUtil.deleteBestEffort(file);
        damaged = true;

        synchronized (bundlePool)
        {
          bundlePool.damagedArtifacts.add(this);
          bundlePool.damagedArtifactsArray = null;
        }

        bundlePool.analyzer.bundlePoolChanged(bundlePool, false, false);
        bundlePool.analyzer.artifactChanged(this);

        for (AnalyzedProfile profile : profiles)
        {
          synchronized (bundlePool)
          {
            profile.damagedArtifacts.add(this);
            profile.damagedArtifactsArray = null;
          }

          bundlePool.analyzer.profileChanged(profile);
        }
      }
    }

    private void deleteUnused(IProgressMonitor monitor)
    {
      monitor.subTask("Deleting " + this);
      IFileArtifactRepository p2BundlePool = bundlePool.getP2BundlePool(monitor);
      p2BundlePool.removeDescriptor(key, monitor);
      damaged = false;

      synchronized (bundlePool)
      {
        bundlePool.artifacts.remove(key);
        bundlePool.artifactsArray = null;

        bundlePool.unusedArtifacts.remove(this);
        bundlePool.unusedArtifactsArray = null;

        bundlePool.damagedArtifacts.remove(this);
        bundlePool.damagedArtifactsArray = null;
      }

      bundlePool.analyzer.bundlePoolChanged(bundlePool, true, false);
    }

    public synchronized boolean repair(Set<URI> repositoryURIs, IProgressMonitor monitor)
    {
      if (!damaged)
      {
        return false;
      }

      if (isUnused())
      {
        deleteUnused(monitor);
        return true;
      }

      monitor.subTask("Repairing " + this);
      if (repositoryURIs == null ? doRepair(monitor) : doRepair(repositoryURIs, monitor))
      {
        damaged = false;
        bundlePool.analyzer.artifactChanged(this);

        synchronized (bundlePool)
        {
          bundlePool.damagedArtifacts.remove(this);
          bundlePool.damagedArtifactsArray = null;
        }

        for (AnalyzedProfile profile : profiles)
        {
          synchronized (bundlePool)
          {
            profile.damagedArtifacts.remove(this);
            profile.damagedArtifactsArray = null;
          }

          bundlePool.analyzer.profileChanged(profile);
        }

        bundlePool.analyzer.bundlePoolChanged(bundlePool, false, false);
        return true;
      }

      return false;
    }

    private boolean doRepair(IProgressMonitor monitor)
    {
      Set<URI> repositoryURIs = bundlePool.getRepositoryURIs();
      SubMonitor progress = SubMonitor.convert(monitor, 1 + repositoryURIs.size()).detectCancelation();

      Set<URI> poolURIs = new HashSet<URI>();
      for (AnalyzedBundlePool pool : bundlePool.analyzer.getBundlePools().values())
      {
        if (pool != bundlePool)
        {
          AnalyzedArtifact otherArtifact = pool.getArtifact(key);
          if (otherArtifact != null && !otherArtifact.isDamaged())
          {
            URI uri = pool.getLocation().toURI();
            poolURIs.add(uri);
          }
        }
      }

      if (!poolURIs.isEmpty())
      {
        if (doRepair(poolURIs, progress))
        {
          return true;
        }
      }

      if (!repositoryURIs.isEmpty())
      {
        if (doRepair(repositoryURIs, progress))
        {
          return true;
        }
      }

      return false;
    }

    private boolean doRepair(Set<URI> repositoryURIs, IProgressMonitor monitor)
    {
      SubMonitor progress = SubMonitor.convert(monitor, repositoryURIs.size()).detectCancelation();
      for (URI uri : repositoryURIs)
      {
        if (doRepair(uri, progress.newChild()))
        {
          return true;
        }
      }

      return false;
    }

    private boolean doRepair(URI repositoryURI, SubMonitor progress)
    {
      IFileArtifactRepository p2BundlePool = bundlePool.getP2BundlePool(progress.newChild());
      IArtifactDescriptor[] localDescriptors = null;

      try
      {
        localDescriptors = p2BundlePool.getArtifactDescriptors(key);
        if (localDescriptors == null || localDescriptors.length == 0)
        {
          return false;
        }

        p2BundlePool.removeDescriptors(localDescriptors, progress.newChild());

        IArtifactRepositoryManager repositoryManager = bundlePool.analyzer.agent.getArtifactRepositoryManager();
        IArtifactRepository repository = repositoryManager.loadRepository(repositoryURI, progress.newChild());
        progress.setTaskName(REPAIR_TASK_NAME);

        IArtifactDescriptor[] remoteDescriptors = repository.getArtifactDescriptors(key);
        for (IArtifactDescriptor remoteDescriptor : remoteDescriptors)
        {
          OutputStream destination = null;

          try
          {
            destination = p2BundlePool.getOutputStream(localDescriptors[0]);

            IStatus status = repository.getArtifact(remoteDescriptor, destination, progress.newChild());
            if (status.getSeverity() == IStatus.OK)
            {
              localDescriptors = null;
              return true;
            }
          }
          finally
          {
            IOUtil.close(destination);
          }
        }
      }
      catch (OperationCanceledException ex)
      {
        throw ex;
      }
      catch (Error err)
      {
        throw err;
      }
      catch (Exception ex)
      {
        P2CorePlugin.INSTANCE.log(ex);
      }
      finally
      {
        restoreDescriptors(p2BundlePool, localDescriptors);
      }

      return false;
    }

    private void restoreDescriptors(IFileArtifactRepository p2BundlePool, IArtifactDescriptor[] oldDescriptors)
    {
      if (oldDescriptors != null && oldDescriptors.length != 0)
      {
        try
        {
          p2BundlePool.addDescriptors(oldDescriptors, new NullProgressMonitor());
        }
        catch (Exception ex)
        {
          P2CorePlugin.INSTANCE.log(ex);
        }
      }
    }
  }
}
