//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.library.layout.IContentValidator;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Section;
import org.eclipse.epf.uma.UmaPackage;

import com.ibm.icu.util.StringTokenizer;

/**
 * utility class to scan content and copy resources to the target location for browsing and publishing
 * 
 * @author Jinhua Xi
 * @since 1.0
 *
 */
public class ContentResourceScanner {

	protected static final Pattern p_image_ref = Pattern
			.compile(
					"(<(img|iframe).*?src\\s*=\\s*\")(.*?)(\")", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	private File sourceRootPath;

	private File targetRootPath;

	private String rootContentPath;
	
	private IContentValidator validator;

	private List processedItems = new ArrayList();

	/**
	 * construct the object with the root path of the source content
	 * @param sourceRootPath File
	 */
	public ContentResourceScanner(File sourceRootPath, File targetRootPath, String rootContentPath) {
		this(sourceRootPath, targetRootPath, rootContentPath, null);
	}

	/**
	 * construct the object instance with the root path of the source content and a content validator
	 * 
	 * @param sourceRootPath File
	 * @param validator IContentValidator
	 */
	public ContentResourceScanner(File sourceRootPath, File targetRootPath, String rootContentPath, 
			IContentValidator validator) {
		this.sourceRootPath = sourceRootPath;
		this.targetRootPath = targetRootPath;
		this.rootContentPath = rootContentPath;
		this.validator = validator;
	}

	/**
	 * set content validator
	 * @param validator IContentValidator
	 */
	public void setValidator(IContentValidator validator) {
		this.validator = validator;
	}

	/**
	 * get the source root path
	 * @return File
	 */
	public File getSourceRootPath() {
		return this.sourceRootPath;
	}
	
	/**
	 * get the target root path
	 * @return File
	 */
	public File getTargetRootPath() {
		return this.targetRootPath;
	}
	
	/**
	 * set the target root path
	 * @param targetRootPath File
	 */
	public void setTargetRootPath(File targetRootPath) {
		this.targetRootPath = targetRootPath;
	}

	/**
	 * resolve the images in the text. copy the image to destination if needed
	 * This is used for copying resources from a library to another destination
	 * 
	 * @param content
	 * @param contentPath
	 *            the content path of the source
	 */
	public void resolveResources(String content, String contentPath) {
		resolveResources(null, content, contentPath);
	}

	/**
	 * resolve the images in the text. copy the image to destination if needed
	 * This is used for copying resources from a library to another destination
	 * 
	 * @param owner MethodElement
	 * @param content String
	 * @param contentPath String
	 *            the content path of the source
	 */
	public void resolveResources(MethodElement owner, String content,
			String contentPath) {
		processedItems.clear();
		ResourceHelper.resolveResources(owner, null, content, contentPath,
				this.sourceRootPath, this.targetRootPath, this.rootContentPath, processedItems,
				validator);
	}

	/**
	 * resolve the images in the text. copy the image to destination if needed
	 * This is used for moving resources within a library ie, when
	 * sourceRootPath.equals(targetRootPath)
	 * 
	 * @param source
	 * @param contentPath
	 *            the content path of the source
	 * @return String
	 */
	public String resolveResourcesPlugin(String content, String contentPath,
			String oldContentPath) {
		StringBuffer sb = new StringBuffer();
		try {
			// process images
			Matcher m = ResourceHelper.p_image_ref.matcher(content);
			while (m.find()) {
				String url = m.group(3);
				url = processResourceUrlPlugin(url, contentPath, oldContentPath);
				m.appendReplacement(sb, m.group(1) + url + m.group(4));
			}
			m.appendTail(sb);

			content = sb.toString();
			sb = new StringBuffer();

			// process attachments
			m = ResourceHelper.p_link_ref_gen.matcher(content);
			while (m.find()) {
				StringBuffer sbLink = new StringBuffer();
				// String tag = m.group(1);
				String urltext = " " + m.group(2) + " "; //$NON-NLS-1$ //$NON-NLS-2$
				if (ResourceHelper.getGuidFromUrl(urltext) == null) {
					Matcher m2 = ResourceHelper.p_link_href_picker
							.matcher(urltext);
					if (m2.find()) {
						String url = m2.group(1).trim().replaceAll("\"", ""); //$NON-NLS-1$ //$NON-NLS-2$
						url = processResourceUrlPlugin(url, contentPath,
								oldContentPath);
						m2.appendReplacement(sbLink, urltext.substring(m2
								.start(), m2.start(1))
								+ url + urltext.substring(m2.end(1), m2.end()));
						m2.appendTail(sbLink);
						m.appendReplacement(sb, content.substring(m.start(), m
								.start(2))
								+ sbLink.toString()
								+ content.substring(m.end(2), m.end()));
					}
				}

			}
			m.appendTail(sb);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * Processes a resource url for moving within a library
	 * 
	 * @param url
	 * @param contentPath
	 *            new plugin path
	 * @param oldContentPath
	 *            old plugin path
	 * @return String
	 */
	private String processResourceUrlPlugin(String url, String contentPath,
			String oldContentPath) {
		String imageFile = ResourceHelper.getFilePathFromUrl(url,
				oldContentPath);
		if (imageFile == null) {
			return url;
		}
		String newUrl = null;
		File source;
		File dest;
		// targetRootPath is set to the target plugin directory
		source = new File(this.sourceRootPath.getParentFile(), imageFile);
		if (imageFile.indexOf(File.separator) != -1) {
			String oldPlugin = imageFile.substring(0, imageFile
					.indexOf(File.separator));
			String newPlugin = this.targetRootPath.getName();
			newUrl = url.replaceFirst(oldPlugin, newPlugin);
			imageFile = imageFile.substring(imageFile.indexOf(File.separator));
		}
		dest = new File(this.targetRootPath, imageFile);

		FileUtil.copyFile(source, dest);

		return newUrl;
	}

	
	/**
	 * copy all resources referenced by the the element and all its contained elements, recursively
	 * @param element EObject
	 */
	public void copyResources(EObject element) {
		
		if ( element == null ) {
			return;
		}
		
		if ( element instanceof DescribableElement ) {
			DescribableElement de = (DescribableElement)element;
			String elementPath = ResourceHelper.getElementPath(de);
			
			//1. icons
			java.net.URI icon = de.getShapeicon();
			if ( icon != null ) {
				String path = icon.getPath();
				FileUtil.copyFile(
						new File(getSourceRootPath(), path), 
						new File(getTargetRootPath(), path));
			}
			
			icon = de.getNodeicon();
			if ( icon != null ) {
				String path = icon.getPath();
				FileUtil.copyFile(
						new File(getSourceRootPath(), path), 
						new File(getTargetRootPath(), path));
			}
			
			// 2. attachments
		
			
			// 3. contents
			ContentDescription desc = de.getPresentation();
			if ( desc.eContainer() != null ) {
				List features = LibraryUtil.getStructuralFeatures(desc);
//				List properties = desc.getInstanceProperties();
								
				// get all string type attributes
				for (int i = 0; i < features.size(); i++) {
					EStructuralFeature feature = (EStructuralFeature) features
							.get(i);
					if ( !(feature instanceof EAttribute) ) {
						continue;
					}
					
					Object value = desc.eGet(feature);
					if ( value == null ) {
						continue;
					}
					
					
					if (feature == UmaPackage.eINSTANCE.getContentDescription_Sections() ) {
						List sections = (List)value;
						for (Iterator it = sections.iterator(); it.hasNext(); ) {
							String text = ((Section)it.next()).getSectionDescription();
							resolveResources(de, text, elementPath);
						}
					}  else if (feature == UmaPackage.eINSTANCE.getGuidanceDescription_Attachments() ) {
						String urls = value.toString().trim();
						if (urls.length() != 0 ) {
							StringTokenizer st = new StringTokenizer(urls, "|"); // this is hardcoded somehow //$NON-NLS-1$
							while (st.hasMoreTokens() ) {
								String url = st.nextToken();
								FileUtil.copyFile(
										new File(getSourceRootPath(), elementPath + url), 
										new File(getTargetRootPath(), elementPath + url));

							}
						}
					} else if ( value instanceof String ) {
						resolveResources(de, value.toString(), elementPath);
					} else {
						// do nothing
					}
				}
			}
		}
	}
	
}
