package org.eclipse.scout.sdk.compatibility.v44.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.internal.FeatureDefinition;
import org.eclipse.scout.sdk.compatibility.PlatformVersionUtility;
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 && dir.trim().length() > 0) {
            liveList.add(svc.newDirectoryLocation(dir));
          }
        }
      }
    });
  }

  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);
  }
}
