/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.javadoc;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.URIUtil;

import org.eclipse.core.resources.IResource;

import org.eclipse.ui.PlatformUI;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelStatusConstants;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IModularClassFile;
import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IOrdinaryClassFile;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;

import org.eclipse.jdt.internal.corext.CorextMessages;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

import org.eclipse.jdt.ui.JavaUI;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;


public class JavaDocLocations {

	private static final String JAR_PROTOCOL= "jar"; //$NON-NLS-1$
	public static final String ARCHIVE_PREFIX= "jar:"; //$NON-NLS-1$

	private static final QualifiedName PROJECT_JAVADOC= new QualifiedName(JavaUI.ID_PLUGIN, "project_javadoc_location"); //$NON-NLS-1$

	private static IClasspathEntry getConvertedEntry(IClasspathEntry entry, IJavaProject project, Map<IPath, String> oldLocationMap) {
		IPath path= null;
		switch (entry.getEntryKind()) {
			case IClasspathEntry.CPE_SOURCE:
			case IClasspathEntry.CPE_PROJECT:
				return null;
			case IClasspathEntry.CPE_CONTAINER:
				convertContainer(entry, project, oldLocationMap);
				return null;
			case IClasspathEntry.CPE_LIBRARY:
				path= entry.getPath();
				break;
			case IClasspathEntry.CPE_VARIABLE:
				path= JavaCore.getResolvedVariablePath(entry.getPath());
				break;
			default:
				return null;
		}
		if (path == null) {
			return null;
		}
		IClasspathAttribute[] extraAttributes= entry.getExtraAttributes();
		for (int i= 0; i < extraAttributes.length; i++) {
			if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(extraAttributes[i].getName())) {
				return null;
			}
		}
		String libraryJavadocLocation= oldLocationMap.get(path);
		if (libraryJavadocLocation != null) {
			CPListElement element= CPListElement.createFromExisting(entry, project);
			element.setAttribute(CPListElement.JAVADOC, libraryJavadocLocation);
			return element.getClasspathEntry();
		}
		return null;
	}

	private static void convertContainer(IClasspathEntry entry, IJavaProject project, Map<IPath, String> oldLocationMap) {
		try {
			IClasspathContainer container= JavaCore.getClasspathContainer(entry.getPath(), project);
			if (container == null) {
				return;
			}

			IClasspathEntry[] entries= container.getClasspathEntries();
			boolean hasChange= false;
			for (int i= 0; i < entries.length; i++) {
				IClasspathEntry curr= entries[i];
				IClasspathEntry updatedEntry= getConvertedEntry(curr, project, oldLocationMap);
				if (updatedEntry != null) {
					entries[i]= updatedEntry;
					hasChange= true;
				}
			}
			if (hasChange) {
				BuildPathSupport.requestContainerUpdate(project, container, entries);
			}
		} catch (CoreException e) {
			// ignore
		}
	}

	/**
	 * Sets the Javadoc location for an archive with the given path.
	 * @param project the Java project
	 * @param url the Javadoc location
	 */
	public static void setProjectJavadocLocation(IJavaProject project, URL url) {
		try {
			String location= url != null ? url.toExternalForm() : null;
			setProjectJavadocLocation(project, location);
		} catch (CoreException e) {
			JavaPlugin.log(e);
		}
	}

	private static void setProjectJavadocLocation(IJavaProject project, String url) throws CoreException {
		project.getProject().setPersistentProperty(PROJECT_JAVADOC, url);
	}

	public static URL getProjectJavadocLocation(IJavaProject project) {
		if (!project.getProject().isAccessible()) {
			return null;
		}
		try {
			String prop= project.getProject().getPersistentProperty(PROJECT_JAVADOC);
			if (prop == null) {
				return null;
			}
			return parseURL(prop);
		} catch (CoreException e) {
			JavaPlugin.log(e);
		}
		return null;
	}

	public static URL getLibraryJavadocLocation(IClasspathEntry entry) {
		if (entry == null) {
			throw new IllegalArgumentException("Entry must not be null"); //$NON-NLS-1$
		}

		int kind= entry.getEntryKind();
		if (kind != IClasspathEntry.CPE_LIBRARY && kind != IClasspathEntry.CPE_VARIABLE) {
			throw new IllegalArgumentException("Entry must be of kind CPE_LIBRARY or CPE_VARIABLE"); //$NON-NLS-1$
		}

		IClasspathAttribute[] extraAttributes= entry.getExtraAttributes();
		for (int i= 0; i < extraAttributes.length; i++) {
			IClasspathAttribute attrib= extraAttributes[i];
			if (IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME.equals(attrib.getName())) {
				return parseURL(attrib.getValue());
			}
		}
		return null;
	}

	public static URL getJavadocBaseLocation(IJavaElement element) throws JavaModelException {
		if (element.getElementType() == IJavaElement.JAVA_PROJECT) {
			return getProjectJavadocLocation((IJavaProject) element);
		}

		IPackageFragmentRoot root= JavaModelUtil.getPackageFragmentRoot(element);
		if (root == null) {
			return null;
		}

		if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
			IClasspathEntry entry= root.getResolvedClasspathEntry();
			URL javadocLocation= getLibraryJavadocLocation(entry);
			if (javadocLocation != null) {
				return getLibraryJavadocLocation(entry);
			}
			entry= root.getRawClasspathEntry();
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_LIBRARY:
				case IClasspathEntry.CPE_VARIABLE:
					return getLibraryJavadocLocation(entry);
				default:
					return null;
			}
		} else {
			return getProjectJavadocLocation(root.getJavaProject());
		}
	}

	public static URL getJavadocLocation(IJavaElement element, boolean includeMemberReference) throws JavaModelException {
		URL baseLocation= getJavadocBaseLocation(element);
		if (baseLocation == null) {
			return null;
		}

		String urlString= baseLocation.toExternalForm();

		StringBuffer urlBuffer= new StringBuffer(urlString);
		if (!urlString.endsWith("/")) { //$NON-NLS-1$
			urlBuffer.append('/');
		}
		
		StringBuffer pathBuffer= new StringBuffer();
		StringBuffer fragmentBuffer= new StringBuffer();

		switch (element.getElementType()) {
			case IJavaElement.PACKAGE_FRAGMENT:
				appendPackageSummaryPath((IPackageFragment) element, pathBuffer);
				break;
			case IJavaElement.JAVA_PROJECT:
			case IJavaElement.PACKAGE_FRAGMENT_ROOT :
				appendIndexPath(pathBuffer);
				break;
			case IJavaElement.IMPORT_CONTAINER :
				element= element.getParent();
				//$FALL-THROUGH$
			case IJavaElement.COMPILATION_UNIT :
				IType mainType= ((ICompilationUnit) element).findPrimaryType();
				if (mainType == null) {
					return null;
				}
				appendTypePath(mainType, pathBuffer);
				break;
			case IJavaElement.CLASS_FILE :
				if (element instanceof IModularClassFile) {
					try {
						appendModuleSummaryPath(((IModularClassFile) element).getModule(), pathBuffer);
					} catch (JavaModelException e) {
						return null;
					}
				} else {
					appendTypePath(((IOrdinaryClassFile) element).getType(), pathBuffer);
				}
				break;
			case IJavaElement.TYPE :
				appendTypePath((IType) element, pathBuffer);
				break;
			case IJavaElement.FIELD :
				IField field= (IField) element;
				appendTypePath(field.getDeclaringType(), pathBuffer);
				if (includeMemberReference) {
					appendFieldReference(field, fragmentBuffer);
				}
				break;
			case IJavaElement.METHOD :
				IMethod method= (IMethod) element;
				appendTypePath(method.getDeclaringType(), pathBuffer);
				if (includeMemberReference) {
					appendMethodReference(method, fragmentBuffer);
				}
				break;
			case IJavaElement.INITIALIZER :
				appendTypePath(((IMember) element).getDeclaringType(), pathBuffer);
				break;
			case IJavaElement.IMPORT_DECLARATION :
				IImportDeclaration decl= (IImportDeclaration) element;

				if (decl.isOnDemand()) {
					IJavaElement cont= JavaModelUtil.findTypeContainer(element.getJavaProject(), Signature.getQualifier(decl.getElementName()));
					if (cont instanceof IType) {
						appendTypePath((IType) cont, pathBuffer);
					} else if (cont instanceof IPackageFragment) {
						appendPackageSummaryPath((IPackageFragment) cont, pathBuffer);
					}
				} else {
					IType imp= element.getJavaProject().findType(decl.getElementName());
					appendTypePath(imp, pathBuffer);
				}
				break;
			case IJavaElement.PACKAGE_DECLARATION :
				IJavaElement pack= element.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
				if (pack != null) {
					appendPackageSummaryPath((IPackageFragment) pack, pathBuffer);
				} else {
					return null;
				}
				break;
			case IJavaElement.JAVA_MODULE:
				IModuleDescription module= (IModuleDescription) element;
				appendModuleSummaryPath(module, pathBuffer);
				break;	
			default :
				return null;
		}

		return getURL(urlBuffer, pathBuffer, fragmentBuffer);
	}

	private static URL getURL(StringBuffer urlBuffer, StringBuffer pathBuffer, StringBuffer fragmentBuffer) {
		try {
			String fragment= fragmentBuffer.length() == 0 ? null : fragmentBuffer.toString();
			try {
				URI relativeURI= new URI(null, null, pathBuffer.toString(), fragment);
				urlBuffer.append(relativeURI.toString());
				return new URL(urlBuffer.toString());
			} catch (URISyntaxException e) {
				JavaPlugin.log(e);
				return new URL(urlBuffer.append(pathBuffer).toString());
			}
		} catch (MalformedURLException e) {
			JavaPlugin.log(e);
		}
		return null;
	}

	private static void appendPackageSummaryPath(IPackageFragment pack, StringBuffer buf) {
		appendModulePath(pack, buf);
		String packPath= pack.getElementName().replace('.', '/');
		buf.append(packPath);
		buf.append("/package-summary.html"); //$NON-NLS-1$
	}

	private static void appendModuleSummaryPath(IModuleDescription module, StringBuffer buf) {
		String moduleName= module.getElementName();
		buf.append(moduleName);
		buf.append("/module-summary.html"); //$NON-NLS-1$
	}

	private static void appendIndexPath(StringBuffer buf) {
		buf.append("index.html"); //$NON-NLS-1$
	}

	private static void appendTypePath(IType type, StringBuffer buf) {
		IPackageFragment pack= type.getPackageFragment();
		appendModulePath(pack, buf);
		String packPath= pack.getElementName().replace('.', '/');
		String typePath= type.getTypeQualifiedName('.');
		if (packPath.length() > 0) {
			buf.append(packPath);
			buf.append('/');
		}
		buf.append(typePath);
		buf.append(".html"); //$NON-NLS-1$
	}

	private static void appendModulePath(IPackageFragment pack, StringBuffer buf) {
		IModuleDescription moduleDescription= getModuleDescription(pack);
		if (moduleDescription != null) {
			String moduleName= moduleDescription.getElementName();
			if (moduleName != null && moduleName.length() > 0) {
				buf.append(moduleName);
				buf.append('/');
			}
		}
	}

	private static IModuleDescription getModuleDescription(IPackageFragment pack) {
		if (pack == null) {
			return null;
		}
		IModuleDescription moduleDescription= null;
		/*
		 * The Javadoc tool for Java SE 11 uses module name in the created URL.
		 * We can't know what format is required, so we just guess by the project's compiler compliance.
		 */
		IJavaProject javaProject= pack.getJavaProject();
		if (javaProject != null && JavaModelUtil.is11OrHigher(javaProject)) {
			if (pack.isReadOnly()) {
				IPackageFragmentRoot root= (IPackageFragmentRoot) pack.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
				if (root != null) {
					moduleDescription= root.getModuleDescription();
				}
			} else {
				try {
					moduleDescription= javaProject.getModuleDescription();
				} catch (JavaModelException e) {
					// do nothing
				}
			}
		}
		return moduleDescription;
	}

	private static void appendFieldReference(IField field, StringBuffer buf) {
		buf.append(field.getElementName());
	}

	private static void appendMethodReference(IMethod meth, StringBuffer buf) throws JavaModelException {
		buf.append(meth.getElementName());

		/*
		 * The Javadoc tool for Java SE 8 changed the anchor syntax and now tries to avoid "strange" characters in URLs.
		 * This breaks all clients that directly create such URLs.
		 * We can't know what format is required, so we just guess by the project's compiler compliance.
		 */
		boolean is18OrHigher= JavaModelUtil.is18OrHigher(meth.getJavaProject());
		buf.append(is18OrHigher ? '-' : '(');
		String[] params= meth.getParameterTypes();
		IType declaringType= meth.getDeclaringType();
		boolean isVararg= Flags.isVarargs(meth.getFlags());
		int lastParam= params.length - 1;
		for (int i= 0; i <= lastParam; i++) {
			if (i != 0) {
				buf.append(is18OrHigher ? "-" : ", "); //$NON-NLS-1$ //$NON-NLS-2$
			}
			String curr= Signature.getTypeErasure(params[i]);
			String fullName= JavaModelUtil.getResolvedTypeName(curr, declaringType);
			if (fullName == null) { // e.g. a type parameter "QE;"
				fullName= Signature.toString(Signature.getElementType(curr));
			}
			if (fullName != null) {
				buf.append(fullName);
				int dim= Signature.getArrayCount(curr);
				if (i == lastParam && isVararg) {
					dim--;
				}
				while (dim > 0) {
					buf.append(is18OrHigher ? ":A" : "[]"); //$NON-NLS-1$ //$NON-NLS-2$
					dim--;
				}
				if (i == lastParam && isVararg) {
					buf.append("..."); //$NON-NLS-1$
				}
			}
		}
		buf.append(is18OrHigher ? '-' : ')');
	}

	/**
	 * Returns the location of the Javadoc.
	 * 
	 * @param element whose Javadoc location has to be found
	 * @param isBinary <code>true</code> if the Java element is from a binary container
	 * @return the location URL of the Javadoc or <code>null</code> if the location cannot be found
	 * @throws JavaModelException thrown when the Java element cannot be accessed
	 * @since 3.9
	 */
	public static String getBaseURL(IJavaElement element, boolean isBinary) throws JavaModelException {
		if (isBinary) {
			// Source attachment usually does not include Javadoc resources
			// => Always use the Javadoc location as base:
			URL baseURL= JavaUI.getJavadocLocation(element, false);
			if (baseURL != null) {
				if (baseURL.getProtocol().equals(JAR_PROTOCOL)) {
					// It's a JarURLConnection, which is not known to the browser widget.
					// Let's start the help web server:
					URL baseURL2= PlatformUI.getWorkbench().getHelpSystem().resolve(baseURL.toExternalForm(), true);
					if (baseURL2 != null) { // can be null if org.eclipse.help.ui is not available
						baseURL= baseURL2;
					}
				}
				return baseURL.toExternalForm();
			}
		} else {
			IResource resource= element.getResource();
			if (resource != null) {
				/*
				 * Too bad: Browser widget knows nothing about EFS and custom URL handlers,
				 * so IResource#getLocationURI() does not work in all cases.
				 * We only support the local file system for now.
				 * A solution could be https://bugs.eclipse.org/bugs/show_bug.cgi?id=149022 .
				 */
				IPath location= resource.getLocation();
				if (location != null)
					return location.toFile().toURI().toString();
			}
		}
		return null;
	}

	/**
	 * Returns the reason for why the Javadoc of the Java element could not be retrieved.
	 * 
	 * @param element whose Javadoc could not be retrieved
	 * @param root the root of the Java element
	 * @return the String message for why the Javadoc could not be retrieved for the Java element or
	 *         <code>null</code> if the Java element is from a source container
	 * @since 3.9
	 */
	public static String getExplanationForMissingJavadoc(IJavaElement element, IPackageFragmentRoot root) {
		String message= null;
		try {
			boolean isBinary= (root.exists() && root.getKind() == IPackageFragmentRoot.K_BINARY);
			if (isBinary) {
				boolean hasAttachedJavadoc= JavaDocLocations.getJavadocBaseLocation(element) != null;
				boolean hasAttachedSource= root.getSourceAttachmentPath() != null;
				IOpenable openable= element.getOpenable();
				boolean hasSource= openable.getBuffer() != null;

				// Provide hint why there's no Java doc
				if (!hasAttachedSource && !hasAttachedJavadoc)
					message= CorextMessages.JavaDocLocations_noAttachments;
				else if (!hasAttachedJavadoc && !hasSource)
					message= CorextMessages.JavaDocLocations_noAttachedJavadoc;
				else if (!hasAttachedSource)
					message= CorextMessages.JavaDocLocations_noAttachedSource;
				else if (!hasSource)
					message= CorextMessages.JavaDocLocations_noInformation;

			}
		} catch (JavaModelException e) {
			message= CorextMessages.JavaDocLocations_error_gettingJavadoc;
			JavaPlugin.log(e);
		}
		return message;
	}

	/**
	 * Handles the exception thrown from JDT Core when the attached Javadoc
	 * cannot be retrieved due to accessibility issues or location URL issue. This exception is not
	 * logged but the exceptions occurred due to other reasons are logged.
	 * 
	 * @param e the exception thrown when retrieving the Javadoc fails
	 * @return the String message for why the Javadoc could not be retrieved
	 * @since 3.9
	 */
	public static String handleFailedJavadocFetch(CoreException e) {
		IStatus status= e.getStatus();
		if (JavaCore.PLUGIN_ID.equals(status.getPlugin())) {
			Throwable cause= e.getCause();
			int code= status.getCode();
			// See bug 120559, bug 400060 and bug 400062
			if (code == IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC_TIMEOUT
					|| (code == IJavaModelStatusConstants.CANNOT_RETRIEVE_ATTACHED_JAVADOC && (cause instanceof FileNotFoundException || cause instanceof SocketException
							|| cause instanceof UnknownHostException
							|| cause instanceof ProtocolException)))
				return CorextMessages.JavaDocLocations_error_gettingAttachedJavadoc;
		}
		JavaPlugin.log(e);
		return CorextMessages.JavaDocLocations_error_gettingJavadoc;
	}

	/**
	 * Parse a URL from a String. This method first tries to treat <code>url</code> as a valid, encoded URL.
	 * If that didn't work, it tries to recover from bad URLs, e.g. the unencoded form we used to use in persistent storage.
	 * 
	 * @param url a URL
	 * @return the parsed URL or <code>null</code> if the URL couldn't be parsed
	 * @since 3.9
	 */
	public static URL parseURL(String url) {
		try {
			try {
				return new URI(url).toURL();
			} catch (URISyntaxException e) {
				try {
					// don't log, since we used to store bad (unencoded) URLs
					if (url.startsWith("file:/")) { //$NON-NLS-1$
						// workaround for a bug in the 3-arg URI constructor for paths that contain '[' or ']':
						return new URI("file", null, url.substring(5), null).toURL(); //$NON-NLS-1$
					} else {
						return URIUtil.fromString(url).toURL();
					}
				} catch (URISyntaxException e1) {
					// last try, not expected to happen
					JavaPlugin.log(e);
					return new URL(url);
				}
			}
		} catch (MalformedURLException e) {
			JavaPlugin.log(e);
			return null;
		}
	}

	/**
	 * Returns the {@link File} of a <code>file:</code> URL. This method tries to recover from bad URLs,
	 * e.g. the unencoded form we used to use in persistent storage.
	 * 
	 * @param url a <code>file:</code> URL
	 * @return the file
	 * @since 3.9
	 */
	public static File toFile(URL url) {
		try {
			return URIUtil.toFile(url.toURI());
		} catch (URISyntaxException e) {
			JavaPlugin.log(e);
			return new File(url.getFile());
		}
	}
}
