//------------------------------------------------------------------------------
// 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.importing.services;

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

import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.MethodElement;


/**
 * utility class to scan and copy resources from the source library to the target library
 * @author Jinhua Xi
 * @since 1.0
 *
 */
public class ResourceScanner {

	public static final Pattern p_src_ref = Pattern.compile("src\\s*=\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
//	protected static final Pattern p_link_ref = Pattern.compile("<a\\s+?([^>]*)>(.*?)</a>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$
	public static final Pattern p_href_ref = Pattern.compile("href\\s*=\\s*\"(.*?)\"", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); //$NON-NLS-1$

	File srcLibRoot;
	File targetLibRoot;
	
	private Map newFileMap = new HashMap();
	private Map existingFileMap = new HashMap();
	
	/**
	 * Creates a new instance.
	 */	
	public ResourceScanner(File srcLibRoot, File targetLibRoot) {
		this.srcLibRoot = srcLibRoot;
		this.targetLibRoot = targetLibRoot;
	}
	
	/**
	 * scan th etext and copy the resources
	 * @param owner MethodElement
	 * @param source String
	 */
	public void scan(MethodElement owner, String source) {
		
		try
		{
			// process images and other src resources
			Matcher m = p_src_ref.matcher(source);
			while ( m.find() )
			{
				String url = m.group(1);
				processUrl(owner, url);
			}

			// process hrefs
			m = p_href_ref.matcher(source);
			
			while ( m.find() )
			{
				String url = m.group(1);
				processUrl(owner, url);
			}			
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	/**
	 * process the url and copy the resource
	 * if the owner element is specified, the url is relative to the owner element, 
	 *otherwise it's relative to the library
	 *
	 * @param owner
	 * @param url
	 */
	private void processUrl(MethodElement owner, String url) {
		
		if ( url == null ) {
			return;
		}
		
		int index = url.indexOf("#"); //$NON-NLS-1$
		if ( index >= 0 )
		{
			url = url.substring(0, index);
		}
		
		index = url.indexOf("?"); //$NON-NLS-1$
		if ( index >= 0 )
		{
			url = url.substring(0, index);
		}
		
		if (url.trim().length() == 0 ) {
			return;
		}
		
		// the url is relative to the owner element
		// need to convert to the path relative to the library root
		File srcFile = null;
		File targetFile = null;
		try {
			if ( owner != null ) {
				String elementPath = ResourceHelper.getElementPath(owner);
				srcFile = new File(new File(srcLibRoot, elementPath), url);		
				targetFile = new File(new File(targetLibRoot, elementPath), url);	
			} else {
				srcFile = new File(srcLibRoot, url);		
				targetFile = new File(targetLibRoot, url);				
			}
			
			if ( srcFile.isFile() && srcFile.exists() ) {

				srcFile = srcFile.getCanonicalFile();
				targetFile = targetFile.getCanonicalFile();
				
				if ( targetFile.exists() ) {
					if ( !existingFileMap.containsKey(srcFile) ) {
						if ( srcFile.length() != targetFile.length() 
								|| srcFile.lastModified() != targetFile.lastModified() )
						{
							existingFileMap.put(srcFile, targetFile);
						}
					}
				} else {
					if ( !newFileMap.containsKey(srcFile) ) {
						newFileMap.put(srcFile, targetFile);
					}
				}
			}
		} catch (IOException e) {
			// Log the error and proceed. TODO
			e.printStackTrace();
		}

	}
	
	/**
	 * Copies resource.
	 */
	public void copyResource(String url) {
		processUrl(null, url);
	}
	
	/**
	 * Copies resource.
	 */
	public void copyResource(MethodElement owner, String url) {
		processUrl(owner, url);
	}
	
	/**
	 * return a list of all the files to be replaced
	 * @return List a list of file path string
	 */
	public List getFilesTobeReplaced() {
		List files = new ArrayList();
		if ( existingFileMap.size() > 0 ) {
			for (Iterator it = existingFileMap.values().iterator(); it.hasNext(); ) {
				File f = (File)it.next();
				if (f != null ) {
					String path = f.getAbsolutePath();
					if ( !files.contains(path) ) {
						files.add(path);
					}
				}
			}
		}
		
		return files;
	}
	
	/**
	 * copy all the files to the destination
	 *
	 */
	public void execute() {
		
		for (Iterator it = newFileMap.entrySet().iterator(); it.hasNext(); ) {
			Map.Entry entry = (Map.Entry)it.next();
			File srcFile = (File) entry.getKey();
			File targetFile = (File) entry.getValue();
			ResourceHelper.copyFile(srcFile, targetFile);
			
			System.out.println("File copied: " + srcFile);
		}	
		
		for (Iterator it = existingFileMap.entrySet().iterator(); it.hasNext(); ) {
			Map.Entry entry = (Map.Entry)it.next();
			File srcFile = (File) entry.getKey();
			File targetFile = (File) entry.getValue();
			ResourceHelper.copyFile(srcFile, targetFile);
			
			System.out.println("File copied: " + srcFile);
		}	
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
