/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation.
 * 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 API and implementation
 *******************************************************************************/
package org.eclipse.cosmos.internal.dr.drs.service.outputter.widget;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Stack;

import org.eclipse.cosmos.internal.dr.drs.service.handler.common.MapParameterImpl;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.AbstractOutputter;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.IIDResolver;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.IOutputterContext;
import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.IParameters;
import org.eclipse.cosmos.provisional.dr.ps.common.IConstants;

public class WidgetProperties extends AbstractOutputter {

	public static final String TAG="tag"; //$NON-NLS-1$
	public static final String FUNCTION="func"; //$NON-NLS-1$
	protected String rootDir = ""; //$NON-NLS-1$
	
	public void initalize(IOutputterContext context, IParameters parameters) throws Exception {
		this.rootDir = context.getRealPath(IConstants.VIEWDIR);		
		super.initalize(context, parameters);
	}
	
	public void render(PrintWriter writer, IParameters input) throws Exception {
		if (input.getParameter(FUNCTION) != null){
			if (input.getParameter(FUNCTION).equals("getTags")){ //$NON-NLS-1$
				generateFileMap(writer);
			}
		}
		else{
			String tag = input.getParameter(TAG);
			String bundleName = context.getInitParameter( "WIDGET_BUNDLE_NAME" );
			ResourceBundle[] RESOURCE_BUNDLES  = null;
			if (bundleName != null){
				String[] bundles = bundleName.split(",");
				RESOURCE_BUNDLES = new ResourceBundle[bundles.length];
				for (int x= 0; x< bundles.length; x++){
					RESOURCE_BUNDLES[x] = ResourceBundle.getBundle(bundles[x]);
					
				}
			}
			else
				RESOURCE_BUNDLES = new ResourceBundle[0];
			
			if (tag != null){
				writer.write("{view:"); //$NON-NLS-1$
				readPropertyFile(tag, IConstants.VIEWFILE, writer, RESOURCE_BUNDLES);
				writer.write(","); //$NON-NLS-1$
				writer.write("dataMap:"); //$NON-NLS-1$
				readPropertyFile(tag, IConstants.DATAMAPFILE, writer, RESOURCE_BUNDLES);		
				writer.write("}"); //$NON-NLS-1$
			}
			else{
				//write empty object
				writer.write("{}"); //$NON-NLS-1$
			}
		}
	}
	
	
	protected void generateFileMap(PrintWriter pw){
		String newFileName = rootDir;
		List<Object[]> dirList = new ArrayList<Object[]>();
		visitAllFiles(new File(rootDir), dirList, new Stack<String>());
			pw.print("["); //$NON-NLS-1$
		    for (int x = 0; x< dirList.size(); x++){
	    		if (x > 0)
	    			pw.print(",");		    		 //$NON-NLS-1$
		    	Object[] dirTags = dirList.get(x);
		    	//don't print the root dir therefore start at index 1
		    	if (dirTags.length > 1){
	    			pw.print("\"");		    		 //$NON-NLS-1$
			    	for (int y = 1 ; y < dirTags.length; y++){
			    		pw.print(dirTags[y]);
			    		if (y <(dirTags.length-1))
			    			pw.print(" ");		    		 //$NON-NLS-1$
			    	}
	    			pw.print("\"");		    		 //$NON-NLS-1$
		    	}
		    }
			pw.print("]"); //$NON-NLS-1$
	}
	
   protected void visitAllFiles(File dir, List<Object[]> dirList, Stack<String> dirStack) {
        if (dir.isDirectory()) {
        	dirStack.push(dir.getName());
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                visitAllFiles(new File(dir, children[i]), dirList, dirStack);
            }
            dirStack.pop();
        } else if (dir.getName().endsWith(IConstants.VIEWFILE)){
        	String parentFile = dir.getParent();        	
        	if (!(dirList.contains(parentFile)))        		
        		dirList.add(dirStack.toArray());
        }
    }	
	protected String generateFilename(String tag, String filename){
		//split tag name
		String tags[] =tag.split(" "); //$NON-NLS-1$
		String newFileName = rootDir+File.separator;
		for (int x = 0; x < tags.length; x++){
			newFileName += tags[x]+File.separator;
		}
		return newFileName+filename;
	}
	protected void readPropertyFile(String tag, String filename, Writer writer, ResourceBundle RESOURCE_BUNDLE[])
			throws Exception {
		generateFilename(tag, filename);
		FileInputStream fis = null;
		ByteArrayOutputStream bos = null;

		try {
			String genFilename = generateFilename(tag, filename);
			File fileExists = new File(genFilename);
			if (fileExists.exists() && fileExists.isFile()){
				fis = new FileInputStream(generateFilename(tag, filename));
				bos = new ByteArrayOutputStream();
	
				int c;
	
				boolean macroStart = false;
				boolean macroStart2 = false;
				StringBuffer macroBuffer = null;
				
				while ((c = fis.read()) != -1){
					if (macroStart){
						if (((char)c) == '{'){
							macroBuffer  = new StringBuffer();
							macroStart2 = true;
						}
						else{
							writer.write('$');
							macroBuffer = null;
						}
						macroStart = false;
					}
					if (((char)c) == '$'){
						macroStart = true;
					}
					
					if (macroBuffer != null){
						if (((char)c) == '}'){
							String macroValue = "";
							for (int x = 0; x< RESOURCE_BUNDLE.length; x++){
								try {
									macroValue = RESOURCE_BUNDLE[x].getString(macroBuffer.toString());
								} catch (MissingResourceException e) {
								}
							}
							if (macroValue == null)
								macroValue = "";
							
							writer.write(macroValue);
							macroBuffer = null;							
						}
						else if (!macroStart2){
							macroBuffer.append((char)c);
						}
						else if (macroStart2){
							macroStart2 = false;
						}
					}
					else if (!macroStart){
							writer.write(c);
					}
				}
			}
		} finally {

			if (fis != null)
				fis.close();

			if (bos != null)
				bos.close();
		}
	}

	public void setIdResolver(IIDResolver idResolver) {
		// TODO Auto-generated method stub

	}
	
	public static final void main(String[] argv) throws Exception{
		PrintWriter pw = new PrintWriter(System.out);
		WidgetProperties out = new WidgetProperties();
		out.rootDir = "D:\\development\\wtp30\\eclipse\\workspace\\org.eclipse.cosmos.examples.e2e.dr.views\\WebContent\\views"; //$NON-NLS-1$
		out.generateFileMap(pw);
	Map input = new HashMap();
		input.put(WidgetProperties.TAG, "nav");
		out.render(pw, new MapParameterImpl(input));
		pw.flush();
		pw.close();
	}

}
