/*
 * @(#)WebRoboTamer.java
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 * RIDUAL : Web Robo Tamer
 * @author  Intelligent Technology Inc.
 * @version 1.00 2002/08/29
 */
package jp.co.nri.rid.web;

import	java.net.*;
import	java.io.File;
import	java.util.*;
import	java.awt.event.*;

import jp.co.iti.fagot.util.ZDebug;

/**
 * web上のデータをダウンロードするクラス。
 */
public class WebRoboTamer{
	/* 20021004 t3-nishimura@nri.co.jp
	 * myProxyHost と myProxyPort を static に変更 */
	//privatec String		myProxyHost		= null;
	//privatec int			myProxyPort		= 8080;
	private	static String		myProxyHost		= null;
	private	static int			myProxyPort		= 8080;

	private	File		mySaveDir		= null;
	private	File		myOutsideSaveDir= null;
	public	boolean		isResourceDownload = true;
	public	boolean		isSwfScan		= true;

	private static final int NUM_ROBOTS = 6;

	private static PasswordAuthenticator myAuthenticator = null;
	
//	static final private String[] PAGE_EXTENSIONS		= {"htm" ,"html" ,"xml" ,"xhtml" ,"shtml" ,"asp" ,"php" ,"jsp" ,"cfm" ,"cgi"};
//	static final private String[] RESOURCE_EXTENSIONS	= {"gif" ,"jpg" ,"jpeg" ,"swf" ,"png" ,"css" ,"svg" ,"class" ,"js" ,"pdf" ,"doc" ,"xls" ,"zip" ,"txt"};
	
	public static void newAuthenticator(){
	}
	
	public void setSaveDir(File dir ,File outside){
		mySaveDir = dir;
		myOutsideSaveDir = outside;
	}
	public void setSaveDir(File dir){ setSaveDir(dir ,null); }
	public void setProxy(String host ,int port){
		if(null==host){
			Properties properties = System.getProperties();
			properties.remove("proxySet");
			properties.remove("proxyHost");
			properties.remove("proxyPort");
		}
		else{
			System.setProperty("proxySet"	,"true");
			System.setProperty("proxyHost"	,host);
			System.setProperty("proxyPort"	,String.valueOf(port));
		}
		myProxyHost = host;
		myProxyPort = port;
	}
	
	public void setAuthorization(String user ,String password){
		if(null==myAuthenticator){
			myAuthenticator = new PasswordAuthenticator();
			Authenticator.setDefault(myAuthenticator);
		}
		
		myAuthenticator.setAuthorization(user ,password);
	}
	
	/*
	 * 。
	 * @since	1.00
	 */
	public void get(String target ,WebMessages messages ,String[] pageExtensions ,String[] contentExtensions){
		ZDebug.trace("get "+target);
		HttpURLConnection.setFollowRedirects(false);
		
		Vector		scanQueue		= new Vector();
		Vector		swfQueue		= new Vector();
		Vector		downloadQueue	= new Vector();
		Hashtable	downloadLog		= new Hashtable();
//		Vector		downloadRobots	= new Vector();
//		Vector		scanRobots		= new Vector();
		WebRoboState roboState		= new WebRoboState();
		
		downloadQueue.add(target);
		
		WebDownloadQueueMap map = new WebDownloadQueueMap();
		map.add(pageExtensions ,scanQueue);
		if(isResourceDownload)	map.add(contentExtensions ,new BlackHoleVector());
		if(isSwfScan)			map.set("swf" ,swfQueue);
		
		try{
			URL url = new URL(target);
			String host	= url.getHost();
			String dir	= url.getPath();
			if(null==dir)	dir = "/";
			if(!dir.endsWith("/")) dir = new File(dir).getParent().replace(File.separatorChar ,'/');
			
			for(int i=NUM_ROBOTS; 0<i; i--){
				WebDownloadRobo downloadRobo = new WebDownloadRobo(roboState ,downloadQueue ,map ,downloadLog ,host ,dir ,messages);
				downloadRobo.setSaveDir(mySaveDir ,myOutsideSaveDir);
				downloadRobo.setRootPath(dir);
//				downloadRobo.setProxy(myProxyHost ,myProxyPort);
				downloadRobo.start();
//				downloadRobots.add(downloadRobo);
			}
			
			for(int i=1;0<i;i--){
				WebScanRobo scanRobo = new WebScanRobo(roboState ,scanQueue ,downloadQueue ,messages);
				scanRobo.start();
//				scanRobots.add(scanRobo);
			}
			
			for(int i=1;0<i;i--){
				WebSwfScanRobo swfRobo = new WebSwfScanRobo(roboState ,swfQueue ,downloadQueue ,messages);
				swfRobo.start();
			}
			
/*
			WebRoboMonitor monitor = new WebRoboMonitor();
			monitor.addWindowListener(new WindowAdapter(){
				public void windowClosing(WindowEvent evt){ System.exit(0); }
			});
			monitor.setDownloadQueue(downloadQueue);
			monitor.setScanQueue(scanQueue);
			monitor.setDownloadRobo(downloadRobots);
			monitor.setScanRobo(scanRobots);
			monitor.show();
*/
			
			while(true){
				try{ Thread.sleep(4000); }catch(InterruptedException e){}
				
				synchronized(swfQueue){ synchronized(scanQueue){ synchronized(downloadQueue){
					if((roboState.alive<=0) && (scanQueue.size()<=0) && (downloadQueue.size()<=0) && (swfQueue.size()<=0))	break;
				} } }
			}
		}catch(MalformedURLException e){ messages.add(messages.BadURLT ,target); }	// new URL()で異常のとき
		finally{ roboState.stopping = true; }
	}
	
/*
	static final public void main(String[] arg) throws Exception {
		WebRoboTamer tamer = new WebRoboTamer();
		switch(arg.length){
		case 4:
			tamer.setAuthorization(arg[2] ,arg[3]);
		case 2:
			tamer.setProxy(arg[1], 8080);
		case 1:
			tamer.setSaveDir(new File("f:/w"));
			tamer.get(arg[0] ,new WebMessages());
			break;
		}
		System.exit(0);
	}
*/
/*
	private class PasswordAuthenticator extends Authenticator{
		private	PasswordAuthentication myAuthentication;
		
		public PasswordAuthenticator(String user,String password){
			myAuthentication = new PasswordAuthentication(user, password.toCharArray());
		}
		
		protected PasswordAuthentication getPasswordAuthentication(){
			if(myProxyPort != getRequestingPort())	return null;
			try{
				if(!myProxyHost.equalsIgnoreCase(getRequestingSite().getHostName()))	return null;
			}catch(NullPointerException e){ return null; }
			
			return myAuthentication;
		}
	}
*/
	
	private class PasswordAuthenticator extends Authenticator{
		private PasswordAuthentication myPasswordAuthentication = null;
		
		public void setAuthorization(String user ,String password){
			// 20021002 null判定追加
			if ( password == null ) {
				myPasswordAuthentication = new PasswordAuthentication(user, new char[1] );
			} else {
				myPasswordAuthentication = new PasswordAuthentication(user, password.toCharArray());
			}
		}
		protected PasswordAuthentication getPasswordAuthentication(){
			if(null == myProxyHost)					return null;
			if(myProxyPort != getRequestingPort())	return null;
			try{
				if(!myProxyHost.equalsIgnoreCase(getRequestingSite().getHostName()))	return null;
			}catch(NullPointerException e){ return null; }
			
			return myPasswordAuthentication;
		}
	}
}
