/*******************************************************************************
 * Copyright (c) 2004 IBM Corporation and others.
 * 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.wst.css.tests.encoding.css;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;

import junit.framework.TestCase;

import org.eclipse.wst.common.encoding.EncodingMemento;
import org.eclipse.wst.common.encoding.IResourceCharsetDetector;
import org.eclipse.wst.css.core.internal.content.CSSResourceEncodingDetector;
import org.eclipse.wst.css.tests.encoding.CSSEncodingTestsPlugin;

public class CSSEncodingTester extends TestCase {

	/**
	 * Ensures that an InputStream has mark/reset support.
	 */
	private static InputStream getMarkSupportedStream(InputStream original) {
		if (original == null)
			return null;
		if (original.markSupported())
			return original;
		return new BufferedInputStream(original);
	}
	private boolean DEBUG = false;
	private final String fileDir = "css/";
	// private final String pluginLocation =
	// TestsPlugin.getInstallLocation().toString();
	private final String fileHome = "testfiles/";
	private final String fileLocation = fileHome + fileDir;
	private int READ_BUFFER_SIZE = 8000;

	private void doTestFileStream(String filename, String expectedIANAEncoding, IResourceCharsetDetector detector) throws IOException {
		File file = CSSEncodingTestsPlugin.getTestFile(filename);
		if (!file.exists())
			throw new IllegalArgumentException(filename + " was not found");
		InputStream inputStream = new FileInputStream(file);
		// InputStream inStream = getClass().getResourceAsStream(filename);
		InputStream istream = getMarkSupportedStream(inputStream);
		try {
			detector.set(istream);
			EncodingMemento encodingMemento = encodingMemento = detector.getEncodingMemento();

			String foundIANAEncoding = null;

			if (encodingMemento != null) {
				foundIANAEncoding = encodingMemento.getDetectedCharsetName();
			}
			// I changed many "equals" to "equalsIgnoreCase" on 11/4/2002,
			// since
			// some issues with SHIFT_JIS vs. Shift_JIS were causing failures.
			// We do want to be tolerant on input, and accept either, but I
			// think
			// that SupportedJavaEncodings needs to be changed to "recommend"
			// Shift_JIS.
			boolean expectedIANAResult = false;
			if (expectedIANAEncoding == null) {
				expectedIANAResult = expectedIANAEncoding == foundIANAEncoding;
			}
			else {
				expectedIANAResult = expectedIANAEncoding.equalsIgnoreCase(foundIANAEncoding);
			}

			assertTrue("encoding test file " + filename + " expected: " + expectedIANAEncoding + " found: " + foundIANAEncoding, expectedIANAResult);
			// a very simple read test ... will cause JUnit error (not fail)
			// if
			// throws exception.
			if (foundIANAEncoding != null) {
				ensureCanRead(filename, foundIANAEncoding, istream);
			}
		}
		finally {
			if (istream != null) {
				istream.close();
			}
			if (inputStream != null) {
				inputStream.close();
			}
		}
	}

	/**
	 * This method just reads to stream, to be sure it can be read per
	 * encoding, without exception.
	 */
	private void ensureCanRead(String filename, String encoding, InputStream inputStream) throws IOException {
		Charset charset = Charset.forName(encoding);
		CharsetDecoder charsetDecoder = charset.newDecoder();
		charsetDecoder.onMalformedInput(CodingErrorAction.REPORT);
		charsetDecoder.onUnmappableCharacter(CodingErrorAction.REPORT);

		InputStreamReader reader = new InputStreamReader(inputStream, charsetDecoder);
		StringBuffer stringBuffer = readInputStream(reader);
		if (DEBUG) {
			System.out.println();
			System.out.println(filename);
			System.out.println(stringBuffer.toString());
		}
	}

	private StringBuffer readInputStream(Reader reader) throws IOException {

		StringBuffer buffer = new StringBuffer();
		int numRead = 0;
		char tBuff[] = new char[READ_BUFFER_SIZE];
		while ((numRead = reader.read(tBuff, 0, tBuff.length)) != -1) {
			buffer.append(tBuff, 0, numRead);
		}
		return buffer;
	}

	public void testBestCase() throws IOException {
		String filename = fileLocation + "nonStandard.css";
		doTestFileStream(filename, "ISO-8859-6", new CSSResourceEncodingDetector());

	}

	public void testEmptyFile() throws IOException {
		String filename = fileLocation + "emptyFile.css";
		doTestFileStream(filename, null, new CSSResourceEncodingDetector());
	}

	public void testEUCJP() throws IOException {
		String filename = fileLocation + "encoding_test_eucjp.css";
		doTestFileStream(filename, "EUC-JP", new CSSResourceEncodingDetector());
	}

	public void testJIS() throws IOException {
		String filename = fileLocation + "encoding_test_jis.css";
		doTestFileStream(filename, "ISO-2022-JP", new CSSResourceEncodingDetector());
	}

	public void testNoEncoding() throws IOException {
		String filename = fileLocation + "noEncoding.css";
		doTestFileStream(filename, null, new CSSResourceEncodingDetector());
	}

	public void testnonStandardIllFormed() throws IOException {
		String filename = fileLocation + "nonStandardIllFormed.css";
		doTestFileStream(filename, "ISO-8859-6", new CSSResourceEncodingDetector());
	}

	public void testnonStandardIllFormed2() throws IOException {
		String filename = fileLocation + "nonStandardIllFormed2.css";
		doTestFileStream(filename, "ISO-8859-6", new CSSResourceEncodingDetector());
	}

	public void testShiftJIS() throws IOException {
		String filename = fileLocation + "encoding_test_sjis.css";
		doTestFileStream(filename, "SHIFT_JIS", new CSSResourceEncodingDetector());
	}

}