package org.bndtools.utils.copy;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;

import org.bndtools.utils.workspace.FileUtils;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;

import aQute.lib.io.IO;

public class ResourceCopier {
	public static IFile copy(URL url, IFile dst, Map<String, String> replaceRegularExpressions,
		IProgressMonitor monitor) throws IOException, CoreException {
		InputStream is = null;
		try {
			SubMonitor progress = SubMonitor.convert(monitor, 2);

			if (url.getPath()
				.endsWith("/")) {
				File file = dst.getProjectRelativePath()
					.toFile();

				if (file.isDirectory())
					return dst; // already done

				if (file.isFile())
					throw new IllegalArgumentException("Expected no file or a directory, but was a file: " + file);

				file.mkdirs();
				return dst; // already done
			}

			ResourceReplacer replacer = null;
			if ((replaceRegularExpressions == null) || replaceRegularExpressions.isEmpty()) {
				is = url.openStream();
			} else {
				replacer = new ResourceReplacer(replaceRegularExpressions, url);
				replacer.start();
				is = replacer.getStream();
			}

			if (dst.exists()) {
				dst.setContents(is, false, true, progress.newChild(2, SubMonitor.SUPPRESS_NONE));
			} else {
				FileUtils.recurseCreate(dst.getParent(), progress.newChild(1, SubMonitor.SUPPRESS_NONE));
				dst.create(is, false, progress.newChild(1, SubMonitor.SUPPRESS_NONE));
			}

			if (replacer != null) {
				try {
					replacer.join();
				} catch (InterruptedException e) {
					/* swallow */
				}
				if (replacer.getResult() != null) {
					throw replacer.getResult();
				}
			}
		} finally {
			IO.close(is);
		}

		return dst;
	}
}
