/*
 * Paraselene
 * Copyright (c) 2009, 2010  Akira Terasaki
 * このファイルは同梱されているLicense.txtに定めた条件に同意できる場合にのみ
 * 利用可能です。
 */
package paraselene.mockup;


import java.util.*;
import java.io.*;
import paraselene.*;
import paraselene.dyna.*;


/**
 * 開発ツール。
 */
public class Make implements OutputNo {
	public String getString( int no ) {
		switch( no ) {
		case 1:
			return Param.PACKAGE.get();
		case 2:
			return Param.OUT_ENCODE.get();
		case 33:
			return Param.PACKAGE_BASE.get();
		case 34:
			return Param.PACKAGE_VIEW.get();
		case 35:
			return Param.PACKAGE_LOGIC.get();
		}
		return null;
	}

	static String SRC_PATH = "source";

	static String escape( String s ) {
		if ( s == null )	return "null";
		char[]	ch = s.toCharArray();
		StringBuilder	buf = new StringBuilder( "\"" );
		for ( int i = 0; i < ch.length; i++ ) {
			if ( ch[i] == '\n' ) {
				buf = buf.append( "\\n" );
			}
			else if ( ch[i] == '"' ) {
				buf = buf.append( "\\\"" );
			}
			else if ( ch[i] == '\\' ) {
				buf = buf.append( "\\\\" );
			}
			else {
				buf = buf.append( ch[i] );
			}
		}
		buf = buf.append( "\"" );
		return buf.toString();
	}

	private static final String EXCLUDE = "exclude";

	private static void ex_copy( File ex ) throws IOException {
		StringBuilder	out_path = new StringBuilder(
			Param.OUT_PATH.get()
		);
		out_path = out_path.append( File.separator );
		out_path = out_path.append( EXCLUDE );
		out_path = out_path.append( File.separator );
		try {
			out_path = out_path.append(
				ex.getParent().substring(Param.HTML_ROOT.get().length() )
			);
		}
		catch( Exception e ){}
		Output.mkdir( out_path.toString() );
		out_path = out_path.append( File.separator );
		out_path = out_path.append( ex.getName() );

		BufferedOutputStream	out = new BufferedOutputStream(
			new FileOutputStream( out_path.toString() )
		);
		BufferedInputStream		in = new BufferedInputStream(
			new FileInputStream( ex )
		);
		byte[]	buf = new byte[1024 * 32];
		while( true ) {
			int	len = in.read( buf );
			if ( len <= 0 )	break;
			out.write( buf, 0, len );
		}
		in.close();
		out.close();
	}

	private static void read( File root )
	throws FileNotFoundException, UnsupportedEncodingException, IOException,
	DynamicPageException {
		if ( !root.exists() ) {
			System.err.println( root.getPath() + " is not found." );
			System.exit( 1);
		}
		File[]	list = root.listFiles();
		for ( int i = 0; i < list.length; i++ ) {
			if ( list[i].isDirectory() ) {
				if ( Param.isIgnoreDir( list[i].getName() ) ) {
					Linker.readme.echoln( list[i].getPath() + " is ignored." );
					continue;
				}
				read( list[i] );
			}
			else {
				if ( Param.isHit( list[i].getName() ) ) {
					String[]	fp = list[i].getName().split( "\\." );
					String	ext = fp[fp.length - 1];
					PrePage	page = null;
					Linker.readme.echoln( list[i].getPath() + " parsing starts." );
					if ( HtmlExt.isHtml( ext ) ) {
						page = new PrePage( list[i] );
					}
					else {
						page = new Download( list[i] );
					}
					Linker.readme.entryPage( page );
					Linker.readme.echoln( list[i].getPath() + " parsing ended." );
				}
				else {
					ex_copy( list[i] );
					Linker.readme.entryExclude( list[i].getPath() );
					Linker.readme.echoln( list[i].getPath() + " was copied." );
				}
			}
		}
	}

	private static void write() throws Exception {
		Output[]	output = {
			new paraselene.mockup.output.source.DummyPage(),
			new paraselene.mockup.output.source.Gate(),
			new paraselene.mockup.output.source.SuperPage(),
			new paraselene.mockup.output.source.Json(),
		};
		String[]	name = {
			"DummyPage.java", "Gate.java", "SuperPage.java", "Json.java"
		};
		Make	mk = new Make();
		for ( int i = 0; i < name.length; i++ ) {
			if ( output[i] == null )	continue;
			StringBuilder	buf = new StringBuilder( SRC_PATH );
			buf = buf.append( File.separator );
			buf = buf.append( name[i] );
			String	p_name = buf.toString();
			File	file = new File( p_name );
			if ( file.exists() ) {
				Linker.readme.echoln( file.toString() + " is not output, because it already exists." );
				continue;
			}
			output[i].write( file, mk, Long.MAX_VALUE );
			Linker.readme.echoln( file.toString() + " was output." );
		}
	}

	public static void main( String[] argc ) throws Exception {
		paraselene.supervisor.Option.setDebugMode();
		Linker.flag = true;
		Date	start = new Date();
		Linker.readme.echoln( Version.getTitle() );
		System.out.println( Version.getCopyRight() );
		Linker.readme.echoln( start.toString() );
		Linker.readme.echoln( "" );
		Linker.readme.echoln(
			System.getProperty( "java.vendor", "unknown vendor" ) + " " +
			System.getProperty( "java.vm.name", "JAVA VM" ) + " " +
			System.getProperty( "java.version", "" )
		);
		Linker.readme.echoln(
			System.getProperty( "os.name", "unknown OS" ) + " " +
			System.getProperty( "os.version", "" )
		);
		Linker.readme.echoln( "\n" );

		Param.helpParam( argc );
		File	file = new File( Config.CONFIG );
		if ( file.exists() ) {
			Config.load( file );
		}
		Param.setParam( argc );
		Param.loadParam();

		StringBuilder	buf = new StringBuilder( Param.OUT_PATH.get() );
		buf = buf.append( File.separator );
		buf = buf.append( SRC_PATH );
		String[]	part = Param.PACKAGE.get().split( "\\." );
		for ( int i = 0; i < part.length; i++ ) {
			buf = buf.append( File.separator );
			buf = buf.append( part[i] );
		}
		SRC_PATH = buf.toString();

		if ( Boolean.valueOf( Param.CLEAR.get() ) ) {
			Linker.readme.echoln( "<DELETE PHASE>" );
			buf = new StringBuilder( Param.OUT_PATH.get() );
			buf = buf.append( File.separator );
			buf = buf.append( EXCLUDE );
			Output.rmdir( buf.toString() );
			buf = new StringBuilder( SRC_PATH );
			buf = buf.append( File.separator );
			buf = buf.append( PrePage.out_dir[0] );
			Output.rmdir( buf.toString() );
			buf = new StringBuilder( SRC_PATH );
			buf = buf.append( File.separator );
			buf = buf.append( Param.PACKAGE_BASE.get() );
			Output.rmdir( buf.toString() );
		}

		Linker.readme.echoln( "<INPUT PHASE>" );
		read( new File( Param.HTML_ROOT.get() ) );
		Linker.readme.echoln( "<OUTPUT PHASE>" );
		if ( Boolean.valueOf( Param.WEB_APP.get() ) ) {
			write();
		}
		Linker.readme.output();
		if ( Boolean.valueOf( Param.WEB_APP.get() ) ) {
			Linker.readme.echoln( "All phase ended. Please confirm Readme.html." );
		}
		long	time = ( new Date().getTime() - start.getTime() + 500 ) / 100;
		Linker.readme.echoln( String.format( "Total time: %.1fsec", (float)time / 10 ) );
	}
}


