/*******************************************************************************
 * Copyright (c) 2010 BSI Business Systems Integration AG.
 * 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:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.sdk.compatibility.v45.internal;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.pde.core.target.ITargetDefinition;
import org.eclipse.pde.core.target.ITargetHandle;
import org.eclipse.pde.core.target.ITargetLocation;
import org.eclipse.pde.core.target.ITargetPlatformService;
import org.eclipse.pde.core.target.LoadTargetDefinitionJob;
import org.eclipse.pde.core.target.NameVersionDescriptor;
import org.eclipse.pde.internal.core.target.ExternalFileTargetHandle;
import org.eclipse.pde.internal.core.target.IUBundleContainer;
import org.eclipse.pde.internal.core.target.WorkspaceFileTargetHandle;
import org.eclipse.scout.sdk.compatibility.P2Utility;
import org.eclipse.scout.sdk.compatibility.PlatformVersionUtility;
import org.eclipse.scout.sdk.compatibility.internal.FeatureDefinition;
import org.eclipse.scout.sdk.compatibility.internal.ScoutCompatibilityActivator;
import org.eclipse.scout.sdk.compatibility.internal.service.ITargetPlatformCompatService;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

@SuppressWarnings("restriction")
public class TargetPlatformCompatService implements ITargetPlatformCompatService {

  private interface ITargetFileModification {
    void contribute(List<ITargetLocation> liveList, Map<IUBundleContainer, Set<FeatureDefinition>> features, ITargetPlatformService svc) throws CoreException;
  }

  @Override
  public IStatus resolveTargetPlatform(IFile targetFile, boolean loadPlatform, IProgressMonitor monitor) throws CoreException {
    ITargetPlatformService targetService = ScoutCompatibilityActivator.getDefault().acquireService(ITargetPlatformService.class);
    ITargetHandle handle = targetService.getTarget(targetFile);
    ITargetDefinition def = handle.getTargetDefinition();
    return resolveTarget(def, loadPlatform, monitor);
  }

  @Override
  public URI getCurrentTargetFile() throws CoreException {
    ITargetPlatformService targetService = ScoutCompatibilityActivator.getDefault().acquireService(ITargetPlatformService.class);
    ITargetHandle workspaceTargetHandle = targetService.getWorkspaceTargetHandle();
    if (workspaceTargetHandle instanceof WorkspaceFileTargetHandle && workspaceTargetHandle.exists()) {
      IFile f = ((WorkspaceFileTargetHandle) workspaceTargetHandle).getTargetFile();
      if (f != null && f.exists()) {
        return f.getLocationURI();
      }
    }
    else if (workspaceTargetHandle instanceof ExternalFileTargetHandle && workspaceTargetHandle.exists()) {
      return ((ExternalFileTargetHandle) workspaceTargetHandle).getLocation();
    }
    return null;
  }

  @Override
  public IStatus resolveTargetPlatform(Set<File> absolutePaths, String targetName, boolean loadPlatform, IProgressMonitor monitor) throws CoreException {
    ITargetPlatformService tpService = ScoutCompatibilityActivator.getDefault().acquireService(ITargetPlatformService.class);
    ITargetDefinition targetDef = tpService.newTarget();
    targetDef.setName(targetName);

    List<ITargetLocation> bundleContainers = new ArrayList<ITargetLocation>();
    for (File dir : absolutePaths) {
      bundleContainers.add(tpService.newDirectoryLocation(dir.getAbsolutePath()));
    }
    targetDef.setTargetLocations(bundleContainers.toArray(new ITargetLocation[bundleContainers.size()]));
    targetDef.setArch(Platform.getOSArch());
    targetDef.setOS(Platform.getOS());
    targetDef.setWS(Platform.getWS());
    targetDef.setNL(Platform.getNL());
    tpService.saveTargetDefinition(targetDef);

    return resolveTarget(targetDef, loadPlatform, monitor);
  }

  private IStatus resolveTarget(ITargetDefinition def, boolean loadPlatform, IProgressMonitor monitor) {
    IStatus result = def.resolve(monitor);
    if (loadPlatform && result.isOK()) {
      LoadTargetDefinitionJob loadJob = new LoadTargetDefinitionJob(def);
      result = loadJob.run(monitor);
    }
    return result;
  }

  @Override
  public void removeInstallableUnitsFromTarget(IFile targetFile, final String[] unitIds) throws CoreException {
    modifyTargetFile(targetFile, new ITargetFileModification() {
      @Override
      public void contribute(List<ITargetLocation> liveList, Map<IUBundleContainer, Set<FeatureDefinition>> features, ITargetPlatformService svc) throws CoreException {
        for (Set<FeatureDefinition> featureOfContainer : features.values()) {
          Iterator<FeatureDefinition> it = featureOfContainer.iterator();
          while (it.hasNext()) {
            FeatureDefinition def = it.next();
            for (String featureToRemove : unitIds) {
              if (featureToRemove != null && featureToRemove.equals(def.id)) {
                it.remove();
              }
            }
          }
        }
      }
    });
  }

  @Override
  public void addDirectoryLocationToTarget(IFile targetFile, final String[] dirs) throws CoreException {
    modifyTargetFile(targetFile, new ITargetFileModification() {
      @Override
      public void contribute(List<ITargetLocation> liveList, Map<IUBundleContainer, Set<FeatureDefinition>> features, ITargetPlatformService svc) {
        for (String dir : dirs) {
          if (dir != null) {
            String cleanDir = dir.trim();
            if (cleanDir.length() > 0) {
              liveList.add(svc.newDirectoryLocation(cleanDir));
            }
          }
        }
      }
    });
  }

  private static IUBundleContainer getContainer(String uri, Set<IUBundleContainer> containers) throws URISyntaxException {
    URI searchUri = URIUtil.fromString(uri);
    for (IUBundleContainer container : containers) {
      for (URI repo : container.getRepositories()) {
        if (URIUtil.sameURI(searchUri, repo)) {
          return container;
        }
      }
    }
    return null;
  }

  @Override
  public void addInstallableUnitToTarget(IFile targetFile, final String unitId, final String version, final String repository, final IProgressMonitor monitor) throws CoreException {
    modifyTargetFile(targetFile, new ITargetFileModification() {
      @Override
      public void contribute(List<ITargetLocation> liveList, Map<IUBundleContainer, Set<FeatureDefinition>> features, ITargetPlatformService svc) throws CoreException {
        try {
          String ver = version;
          if (ver == null || ver.trim().length() < 1) {
            ver = P2Utility.getLatestVersion(unitId, URIUtil.fromString(repository), monitor);
          }

          IUBundleContainer container = getContainer(repository, features.keySet());
          FeatureDefinition fd = new FeatureDefinition();
          fd.id = unitId;
          fd.version = ver;
          if (container == null) {
            URI uri = URIUtil.fromString(repository);
            IUBundleContainer newIULocation = (IUBundleContainer) svc.newIULocation(new String[]{unitId}, new String[]{ver}, new URI[]{uri}, 0);
            Set<FeatureDefinition> set = new HashSet<FeatureDefinition>(1);
            set.add(fd);
            features.put(newIULocation, set);
          }
          else {
            features.get(container).add(fd);
          }
        }
        catch (URISyntaxException e) {
          throw new CoreException(new Status(IStatus.ERROR, ScoutCompatibilityActivator.PLUGIN_ID, "Unable to parse url '" + repository + "'.", e));
        }
      }
    });
  }

  private List<NameVersionDescriptor> getFeatures(IUBundleContainer iubc) throws CoreException {
    final String INSTALLABLE_UNIT = "unit"; // from org.eclipse.pde.internal.core.target.TargetDefinitionPersistenceHelper.INSTALLABLE_UNIT
    final String ATTR_ID = "id"; // from org.eclipse.pde.internal.core.target.TargetDefinitionPersistenceHelper.ATTR_ID
    final String ATTR_VERSION = "version"; // from org.eclipse.pde.internal.core.target.TargetDefinitionPersistenceHelper.ATTR_VERSION
    try {
      String xml = iubc.serialize();
      DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document document = docBuilder.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
      NodeList childNodes = document.getDocumentElement().getChildNodes();
      ArrayList<NameVersionDescriptor> result = new ArrayList<NameVersionDescriptor>(childNodes.getLength());
      for (int i = 0; i < childNodes.getLength(); i++) {
        Node n = childNodes.item(i);
        if (n.getNodeType() == Node.ELEMENT_NODE && INSTALLABLE_UNIT.equals(n.getNodeName())) {
          Element e = (Element) n;
          if (e.hasAttribute(ATTR_ID)) {
            String id = e.getAttribute(ATTR_ID);
            String version = e.getAttribute(ATTR_VERSION);
            result.add(new NameVersionDescriptor(id, version));
          }
        }
      }
      return result;
    }
    catch (Exception e) {
      throw new CoreException(new Status(IStatus.ERROR, ScoutCompatibilityActivator.PLUGIN_ID, "Unable to parse installable units.", e));
    }
  }

  /**
   * workaround for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=432494
   */
  private Set<FeatureDefinition> getValueOf(Map<IUBundleContainer, Set<FeatureDefinition>> map, IUBundleContainer objectToFind) {
    for (Entry<IUBundleContainer, Set<FeatureDefinition>> entry : map.entrySet()) {
      if (objectToFind != null && objectToFind.equals(entry.getKey())) {
        return entry.getValue();
      }
    }
    return null;
  }

  private void modifyTargetFile(IFile targetFile, ITargetFileModification modification) throws CoreException {
    ITargetPlatformService svc = ScoutCompatibilityActivator.getDefault().acquireService(ITargetPlatformService.class);
    ITargetHandle handle = svc.getTarget(targetFile);
    ITargetDefinition td = handle.getTargetDefinition();
    ITargetLocation[] features = td.getTargetLocations();
    int size = 1;
    if (features != null) {
      size += features.length;
    }

    Map<IUBundleContainer, Set<FeatureDefinition>> p2FeatureMap = new HashMap<IUBundleContainer, Set<FeatureDefinition>>(size);
    List<ITargetLocation> locations = new ArrayList<ITargetLocation>(size);
    if (features != null) {
      for (ITargetLocation container : features) {
        if (container instanceof IUBundleContainer) {
          IUBundleContainer iubc = (IUBundleContainer) container;
          List<NameVersionDescriptor> fs = getFeatures(iubc);

          Set<FeatureDefinition> featureSet = getValueOf(p2FeatureMap, iubc);
          if (featureSet == null) {
            featureSet = new HashSet<FeatureDefinition>(fs.size());
            p2FeatureMap.put(iubc, featureSet);
          }

          for (NameVersionDescriptor f : fs) {
            FeatureDefinition fd = new FeatureDefinition();
            fd.id = f.getId();
            fd.version = f.getVersion();
            featureSet.add(fd);
          }
        }
        else {
          locations.add(container);
        }
      }
    }

    modification.contribute(locations, p2FeatureMap, svc);

    for (Entry<IUBundleContainer, Set<FeatureDefinition>> entry : p2FeatureMap.entrySet()) {
      if (!entry.getValue().isEmpty()) {
        String[] unitIds = new String[entry.getValue().size()];
        String[] versions = new String[entry.getValue().size()];
        int i = 0;
        for (FeatureDefinition f : entry.getValue()) {
          unitIds[i] = f.id;
          if (f.version == null) {
            versions[i] = PlatformVersionUtility.EMPTY_VERSION_STR;
          }
          else {
            versions[i] = f.version;
          }
          i++;
        }

        locations.add(svc.newIULocation(unitIds, versions, entry.getKey().getRepositories(), IUBundleContainer.INCLUDE_CONFIGURE_PHASE | IUBundleContainer.INCLUDE_SOURCE));
      }
    }

    td.setTargetLocations(locations.toArray(new ITargetLocation[locations.size()]));
    svc.saveTargetDefinition(td);
  }
}
