/*********************************************************************
 * Copyright (c) 2009 - 2012 SpringSource, a division of VMware, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.virgo.ide.manifest.core;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Dictionary;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.virgo.ide.facet.core.FacetCorePlugin;
import org.eclipse.virgo.ide.facet.core.FacetUtils;
import org.eclipse.virgo.ide.manifest.internal.core.model.BundleManifestHeader;
import org.eclipse.virgo.ide.module.core.ServerModuleDelegate;
import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
import org.eclipse.virgo.util.osgi.manifest.BundleManifestFactory;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.osgi.framework.Constants;

/**
 * Helper methods to located and load {@link BundleManifest} instances.
 *
 * @author Christian Dupuis
 * @author Steffen Pingel
 * @author Martin Lippert
 * @since 1.0.0
 */
public class BundleManifestUtils {

    /** URL file schema */
    private static final String FILE_SCHEME = "file";

    /**
     * Returns a {@link BundleManifest} instance for the given <code>javaProject</code>.
     * <p>
     * This implementation searches the source folders of the {@link IJavaProject} and returns the first found
     * META-INF/MANIFEST.MF as the valid manifest.
     */
    public static BundleManifest getBundleManifest(IJavaProject javaProject, boolean testBundle) {
        IFile manifestFile = locateManifest(javaProject, testBundle);
        if (manifestFile != null) {
            try {
                return BundleManifestFactory.createBundleManifest(new InputStreamReader(manifestFile.getContents(true)));
            } catch (Exception e) {
            }
        }
        return null;
    }

    /**
     * Locates the {@link IResource} representing the MANIFEST.MF of a <code>javaProject</code>.
     * <p>
     * This implementation searches the source folders of the {@link IJavaProject} and returns the first found
     * META-INF/MANIFEST.MF as the valid manifest.
     */
    public static IFile locateManifest(IJavaProject javaProject, boolean testBundle) {
        String manifestLocation = testBundle ? BundleManifestCorePlugin.TEST_MANIFEST_FILE_LOCATION : BundleManifestCorePlugin.MANIFEST_FILE_LOCATION;
        try {
            for (IClasspathEntry entry : ServerModuleDelegate.getSourceClasspathEntries(javaProject.getProject(), testBundle)) {
                IPath path = entry.getPath().append(manifestLocation).removeFirstSegments(1);
                IFile manifestFileHandle = javaProject.getProject().getFile(path);
                if (manifestFileHandle.exists()) {
                    return manifestFileHandle;
                }
            }

            if (FacetedProjectFramework.hasProjectFacet(javaProject.getProject(), FacetCorePlugin.WEB_FACET_ID)) {
                WebArtifactEdit webArtifact = WebArtifactEdit.getWebArtifactEditForRead(javaProject.getProject());
                if (webArtifact != null) {
                    IPath webDotXmlPath = webArtifact.getDeploymentDescriptorPath();
                    if (webDotXmlPath != null) {
                        IPath path = webDotXmlPath.removeLastSegments(2).append(manifestLocation).removeFirstSegments(1);
                        IFile manifestFileHandle = javaProject.getProject().getFile(path);
                        if (manifestFileHandle.exists()) {
                            return manifestFileHandle;
                        }
                    }
                }
            }

        } catch (Exception e) {
        }
        return null;
    }

    /**
     * Returns a full qualified location of the META-INF folder.
     * <p>
     * This implementation searches the source folders of the {@link IJavaProject} and returns the first found
     * META-INF/MANIFEST.MF as the valid manifest.
     */
    public static String locateManifestFolder(IJavaProject javaProject) {
        IResource resource = locateManifest(javaProject, false);
        if (resource != null) {
            IContainer container = resource.getParent().getParent();
            IPath location = container.getRawLocation();
            if (location != null) {
                return location.toString();
            }
        }
        return null;
    }

    /**
     * Returns a {@link File} instance for the given <code>javaProject</code>.
     * <p>
     * This implementation searches the source folders of the {@link IJavaProject} and returns the first found
     * META-INF/MANIFEST.MF as the valid manifest.
     */
    public static File locateManifestFile(IJavaProject javaProject, boolean testBundle) {
        IResource resource = locateManifest(javaProject, testBundle);
        if (resource != null) {
            URI uri = convertResourceToUrl(resource);
            if (uri != null) {
                return new File(uri);
            }
        }
        return null;
    }

    /**
     * Converts a given {@link IResource} into a full qualified {@link URI} honoring eventual used Eclipse variables in
     * the path expression.
     */
    private static URI convertResourceToUrl(IResource resource) {
        if (resource != null) {
            URI uri = resource.getRawLocationURI();
            if (uri != null) {
                String scheme = uri.getScheme();
                if (FILE_SCHEME.equalsIgnoreCase(scheme)) {
                    return uri;
                } else if ("sourcecontrol".equals(scheme)) {
                    // special case of Rational Team Concert
                    IPath path = resource.getLocation();
                    File file = path.toFile();
                    if (file.exists()) {
                        return file.toURI();
                    }
                } else {
                    IPathVariableManager variableManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
                    return variableManager.resolveURI(uri);
                }
            }
        }
        return null;
    }

    /**
     * Finds a {@link IResource} identified by a given <code>path</code> in the given <code>project</code>
     */
    private static IResource findResource(IProject project, IPath path) {
        if (path != null && project != null && path.removeFirstSegments(1) != null) {
            return project.findMember(path.removeFirstSegments(1));
        }
        return null;
    }

    /**
     * Dumps a new MANIFEST.MF into the given {@link IJavaProject}.
     */
    public static void createNewBundleManifest(IJavaProject javaProject, String symbolicName, String bundleVersion, String providerName,
        String bundleName, String serverModule, Map<String, String> properties) {

        BundleManifest manifest = null;

        File existingManifestFile = locateManifestFile(javaProject, false);
        if (existingManifestFile != null) {
            FileReader reader = null;
            try {
                reader = new FileReader(existingManifestFile);
                manifest = BundleManifestFactory.createBundleManifest(new FileReader(existingManifestFile));
            } catch (FileNotFoundException e) {
            } catch (IOException e) {
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                    }
                }
            }
        } else {
            manifest = BundleManifestFactory.createBundleManifest();
        }

        manifest.setBundleManifestVersion(2);
        Dictionary<String, String> dictonary = manifest.toDictionary();
        if (StringUtils.isNotBlank(symbolicName)) {
            dictonary.put(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
        }
        if (StringUtils.isNotBlank(bundleVersion)) {
            dictonary.put(Constants.BUNDLE_VERSION, bundleVersion);
        }
        if (StringUtils.isNotBlank(bundleName)) {
            dictonary.put(Constants.BUNDLE_NAME, bundleName);
        }
        if (StringUtils.isNotBlank(providerName)) {
            dictonary.put(Constants.BUNDLE_DESCRIPTION, providerName);
        }

        for (Map.Entry<String, String> entry : properties.entrySet()) {
            if (StringUtils.isNotEmpty(entry.getValue()) && StringUtils.isNotEmpty(entry.getKey())) {
                dictonary.put(entry.getKey(), entry.getValue());
            }
        }

        Writer writer = null;
        try {
            if (existingManifestFile != null) {
                writer = new FileWriter(existingManifestFile);
            } else {
                writer = new FileWriter(getFirstPossibleManifestFile(javaProject.getProject(), false).getRawLocation().toFile());
            }
            BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(dictonary);
            bundleManifest.write(writer);
        } catch (IOException e) {
        } finally {
            if (writer != null) {
                try {
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static void createNewParManifest(IProject project, String symbolicName, String version, String name, String description) {
        Dictionary<String, String> manifest = BundleManifestFactory.createBundleManifest().toDictionary();
        if (StringUtils.isNotBlank(symbolicName)) {
            manifest.put("Application-SymbolicName", symbolicName);
        }
        if (StringUtils.isNotBlank(version)) {
            manifest.put("Application-Version", version);
        }
        if (StringUtils.isNotBlank(name)) {
            manifest.put("Application-Name", name);
        }
        if (StringUtils.isNotBlank(description)) {
            manifest.put("Application-Description", description);
        }

        Writer writer = null;
        try {
            writer = new FileWriter(getFirstPossibleManifestFile(project, false).getRawLocation().toFile());
            BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(manifest);
            bundleManifest.write(writer);
        } catch (IOException e) {
        } finally {
            if (writer != null) {
                try {
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public static IFile getFirstPossibleManifestFile(final IProject project, boolean isTestManifest) {
        try {
            if (FacetUtils.hasNature(project, JavaCore.NATURE_ID)) {

                List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(
                    ServerModuleDelegate.getSourceClasspathEntries(project, isTestManifest));
                Collections.sort(entries, new Comparator<IClasspathEntry>() {

                    public int compare(IClasspathEntry o1, IClasspathEntry o2) {
                        String s1 = o1.getPath().toString();
                        String s2 = o2.getPath().toString();
                        if (("/" + project.getName() + "/src/main/resources").equals(s1)) {
                            return -1;
                        } else if (("/" + project.getName() + "/src/test/resources").equals(s1)) {
                            return -1;
                        }
                        if (("/" + project.getName() + "/src/main/resources").equals(s2)) {
                            return 1;
                        } else if (("/" + project.getName() + "/src/test/resources").equals(s2)) {
                            return 1;
                        }
                        return s1.compareTo(s2);
                    }
                });

                for (IClasspathEntry entry : entries) {
                    return createNewManifestInFolder(findResource(project, entry.getPath()), isTestManifest);
                }
            } else {
                return createNewManifestInFolder(project, isTestManifest);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static IFile createNewManifestInFolder(IResource resource, boolean isTestManifest) throws CoreException {
        String manifestFilePath = "META-INF/"
            + (isTestManifest ? BundleManifestCorePlugin.TEST_MANIFEST_FILE_NAME : BundleManifestCorePlugin.MANIFEST_FILE_NAME);
        IFile manifestFile = null;
        if (resource instanceof IFolder) {
            manifestFile = ((IFolder) resource).getFile(manifestFilePath);
        } else if (resource instanceof IProject) {
            manifestFile = ((IProject) resource).getFile(manifestFilePath);
        }
        if (manifestFile != null && !manifestFile.exists()) {
            if (!manifestFile.getParent().exists()) {
                ((IFolder) manifestFile.getParent()).create(true, true, new NullProgressMonitor());
            }
            manifestFile.create(new ByteArrayInputStream("Manifest-Version: 1.0".getBytes()), true, new NullProgressMonitor());
        }
        return manifestFile;
    }

    public static int getLineNumber(IDocument document, BundleManifestHeader header, String valueSubstring) {
        // make sure that we have a line number in case the bundle model is crashed
        if (header == null) {
            return 0;
        }

        for (int l = header.getLineNumber(); l < header.getLineNumber() + header.getLinesSpan(); l++) {
            try {
                IRegion lineRegion = document.getLineInformation(l);
                String lineStr = document.get(lineRegion.getOffset(), lineRegion.getLength());
                if (lineStr.indexOf(valueSubstring) >= 0) {
                    return l + 1;
                }
            } catch (BadLocationException ble) {
            }
        }
        // it might span multiple lines, try a longer algorithm
        try {
            IRegion lineRegion = document.getLineInformation(header.getLineNumber());
            String lineStr = document.get(lineRegion.getOffset(), lineRegion.getLength());
            for (int l = header.getLineNumber() + 1; l < header.getLineNumber() + header.getLinesSpan(); l++) {
                lineRegion = document.getLineInformation(l);
                lineStr += document.get(lineRegion.getOffset() + 1/* the space */, lineRegion.getLength());
                if (lineStr.indexOf(valueSubstring) >= 0) {
                    return l;
                }
            }
        } catch (BadLocationException ble) {
        }
        return header.getLineNumber() + 1;
    }

    public static int getPackageLineNumber(IDocument document, BundleManifestHeader header, ManifestElement element) {
        String packageName = element.getValue();
        if (element.getDirectiveKeys() != null || element.getKeys() != null) {
            return getLineNumber(document, header, packageName + ";");
        }

        // check for this exact package on the last line
        try {
            IRegion lineRegion = document.getLineInformation(header.getLineNumber() + header.getLinesSpan() - 1);
            String lineStr = document.get(lineRegion.getOffset(), lineRegion.getLength());
            if (lineStr.endsWith(packageName)) {
                return header.getLineNumber() + header.getLinesSpan();
            }
        } catch (BadLocationException ble) {
        }

        // search all except last line
        return getLineNumber(document, header, packageName + ",");
    }

}
