/*
 * Copyright(C) 2007 t-doi,All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.amritaj;

import java.io.File;
import java.io.FileInputStream;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

public class TemplateFileTest extends TestCase {
	private String source = null;
	private String expected = null;
	private String result = null;
	private Map<String, Object> data = null;
	private Object data2 = null;
	
	@Override
	protected void setUp() throws Exception {
		super.setUp();
	}
	
//	public void testNormalExpand() {
//		TemplateFile tmpl = new TemplateFile("src\\test\\resource\\template.html");
//		StringWriter sw = new StringWriter();
//		
//		HogePage page = new HogePage();
//		
//		tmpl.expand(sw, page);
//		
//		assertEquals("<p>Hello World!</p>", sw.toString());
//		
//	}
	
	public void testTest1() {
		source = "src\\test\\resource\\test1.html";
		expected = "src\\test\\resource\\comp\\test1.html";
		
		data = new HashMap<String, Object>();
		
		ArrayList<Map> nameAuthorList = new ArrayList<Map>();
		
		Map<String, String> nameAuthor = new HashMap<String, String>();
		nameAuthor.put("name", "Ruby");
		nameAuthor.put("author", "matz");
		
		nameAuthorList.add(nameAuthor);
		
		nameAuthor = new HashMap<String, String>();
		nameAuthor.put("name", "perl");
		nameAuthor.put("author", "Larry Wall");
		
		nameAuthorList.add(nameAuthor);
		
		nameAuthor = new HashMap<String, String>();
		nameAuthor.put("name", "python");
		nameAuthor.put("author", "Guido van Rossum");
		
		nameAuthorList.add(nameAuthor);
		
		data.put("table1", nameAuthorList);

		scenario();
		verify();
	}

	
	public class Page {
		public String getPageTitle() {
			return "Amrita2";
		}
		
		public String getHeaderTitle() {
			return "Hello, Amrita2";
		}
		
		public Text getText() {
			return new Text();
		}
	}
	
	public class Text {
		public String getTemplate() {
			return "Amrita2";
		}
		
		public String getLang() {
			return "Ruby";
		}
	}
	
	public void testTest2() {
		source = "src\\test\\resource\\test2.html";
		expected = "src\\test\\resource\\comp\\test2.html";
		
		data2 = new Page();
		
		scenario2();
		verify();

	}
	
	public class Table {
		
		private ArrayList<AttrArray> attrList = new ArrayList<AttrArray>();
		
		public ArrayList<AttrArray> getTable1() {
			return attrList;
		}
		
		public void addAttr(AttrArray attr) {
			attrList.add(attr);
		}
	}
	
	public class Author {
		private String name;
		private String author;
		
		public Author(String name, String author) {
			this.name = name;
			this.author = author;
		}
		
		public String gatName() {
			return name;
		}
		
		public String gatAuthor() {
			return author;
		}
	}
	
	public void testTest3() {
		source = "src\\test\\resource\\test3.html";
		expected = "src\\test\\resource\\comp\\test3.html";
		Table table = new Table();
		
		AttrArray attr = new AttrArray();
		attr.add("bgcolor", "blue");
		attr.setReplaceValue(new Author("ruby", "matz"));
		
		table.addAttr(attr);
		
		attr = new AttrArray();
		attr.add("bgcolor", "red");
		attr.setReplaceValue(new Author("perl", "Larry Wall"));
		
		table.addAttr(attr);
		
		attr = new AttrArray();
		attr.add("bgcolor", "blue");
		attr.setReplaceValue(new Author("python", "Guido van Rossum"));
		
		table.addAttr(attr);
		
		data2 = table;
		
		scenario2();
		verify();		
	}
	
	public class CheckBoxPage {
		public String getHoge() {
			return "hoge";
		}
		
		public String getFuga() {
			return "fuga";
		}
		
		public String getFoo() {
			return null;
		}
		
		public String getBar() {
			return "bar3";
		}
	}
	
	public void testTest4() {
		source = "src\\test\\resource\\test4.html";
		expected = "src\\test\\resource\\comp\\test4.html";

		data2 = new CheckBoxPage();
		
		scenario2();
		verify();		
	}
	
	private void scenario() {
		TemplateFile tmpl = new TemplateFile(source);
		StringWriter sw = new StringWriter();
		
		tmpl.setEncode("MS932");
		tmpl.setHandleString("am:src");
		
		tmpl.expand(sw, data);
		
		result = sw.toString();
		
	}
	
	private void scenario2() {
		TemplateFile tmpl = new TemplateFile(source);
		StringWriter sw = new StringWriter();
		
		tmpl.setEncode("MS932");
		tmpl.setHandleString("am:src");
		
		tmpl.expand(sw, data2);
		
		result = sw.toString();
		
	}
	
	
	private void verify() {
		expected = expectedHelper(expected);
		expected = expected.replaceAll("\r", "");
		assertEquals(expected, result);
	}
	
	private String expectedHelper(String expected) {
		File f = new File(expected);
		FileInputStream ifs = null;
		StringBuilder builder = new StringBuilder();
		try {
			ifs = new FileInputStream(f);
			FileChannel fc = ifs.getChannel();
			ByteBuffer bb = ByteBuffer.allocateDirect((int)fc.size());
			fc.read(bb);
			bb.clear();
			byte[] bytes = new byte[bb.capacity()];
			bb.get(bytes);
			builder.append(new String(bytes));
		}
		catch (Exception e) {
			fail();
		}
		finally {
			if (ifs != null) {
				try {
					ifs.close();
				}
				catch (Exception ignore){}
			}
		}
		return builder.toString();
	}
}
