package jp.hasc.hasctool.core.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Arrays;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.widgets.Display;


/**
 * @author iwasaki
 */
public class CoreUtil {
	/** logger for this class */
	private final static org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory
			.getLog(CoreUtil.class);
	
	public static void throwAsRuntimeException(Throwable th) {
		if (th instanceof RuntimeException) {
			throw (RuntimeException)th;
		}else{
			throw new RuntimeException(th);
		}
	}
	
	public static void copyToClipboard(Display display, String text) {
		final Clipboard cb = new Clipboard(display);
		TextTransfer textTransfer = TextTransfer.getInstance();
		cb.setContents(new Object[] { text },
				new Transfer[] { textTransfer });
	}
	
	public static String readReaderAsString(Reader r) throws IOException {
		StringBuilder sb=new StringBuilder();
		char[] buff=new char[1024];
		while(true) {
			int len=r.read(buff);
			if (len<0) break;
			sb.append(buff,0,len);
		}
		return sb.toString();
	}
	
	public static void copyStreamAndClose(InputStream inps, OutputStream outs) throws IOException {
		try{
			copyStream(inps, outs, 1024);
		}finally{
			inps.close();
			outs.close();
		}
	}

	public static void copyStream(InputStream inps, OutputStream outs, int buffsize)
			throws IOException {
		byte[] buff=new byte[buffsize];
		while(true) {
			int bytes=inps.read(buff);
			if (bytes<0) break;
			outs.write(buff,0,bytes);
		}
	}

	private static String hexDigits_="0123456789abcdef";
	
	public static int hexToInt(String hexStr) {
		int r=0;
		hexStr=hexStr.toLowerCase();
		for(int i=0,num=hexStr.length();i<num;++i) {
			char c=hexStr.charAt(i);
			int idx=hexDigits_.indexOf(c);
			if (idx<0) throw new IllegalArgumentException(hexStr);
			r=r*16+idx;
		}
		return r;
	}
	
	public static String changeFileExt(String path, String newExt)
	{
		int pidx = Math.max(path.lastIndexOf('/'),path.lastIndexOf('\\'));
		int didx = path.lastIndexOf('.');
		if (didx>pidx) path = path.substring(0,didx);
		return path + newExt;
	}
	
	public static IFile convertAudioFile(IFile f) throws Exception{
		// dest path
		String fname = f.getName();
		String destName=changeFileExt(fname,".wav");
		if (f.equals(destName)) return f;
		IFile destf=f.getParent().getFile(new Path(destName));
		// convert
		File rf = f.getRawLocation().toFile();
		File destrf = destf.getRawLocation().toFile();
		String[] cmd = null;
		String ffmpeg_path = System.getProperty("HASCTOOL_FFMPEG_CMD");
		if (ffmpeg_path==null) ffmpeg_path = System.getenv("HASCTOOL_FFMPEG_CMD");
		String os = Platform.getOS();
		if (ffmpeg_path==null && os.equals(Platform.OS_MACOSX)) {
			cmd = new String[]{"afconvert","-f","WAVE","-d","LEI16",rf.toString(),destrf.toString()};
		}else{
			if (ffmpeg_path==null) ffmpeg_path = "ffmpeg";
			cmd = new String[]{ffmpeg_path,"-y","-i",rf.toString(),destrf.toString()};
		}
		LOG.debug("cmd: "+Arrays.toString(cmd));
		Process pr = new ProcessBuilder(cmd).redirectErrorStream(true).start();
		InputStream stdout=pr.getInputStream();
		//copyStream(stdout, System.err, 1);
		LOG.debug("output: "+readReaderAsString(new InputStreamReader(stdout)));
		stdout.close();
		int ret=pr.waitFor();
		if (ret!=0) throw new RuntimeException("Command execution failed: ret="+ret);
		// refresh
		destf.refreshLocal(IResource.DEPTH_ZERO, null);
		return destf;
	}
}
