/*******************************************************************************
 * Copyright (c) 2006, 2014 BEA Systems, Inc. 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:
 *    wharley@bea.com - initial API and implementation
 *    
 *******************************************************************************/

package org.eclipse.jdt.internal.compiler.apt.dispatch;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

import javax.tools.ForwardingJavaFileObject;
import javax.tools.JavaFileObject;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;

/**
 * A delegating JavaFileObject that hooks the close() methods of the Writer
 * or OutputStream objects that it produces, and notifies the annotation
 * dispatch manager when a new compilation unit is produced.
 */
public class HookedJavaFileObject extends
		ForwardingJavaFileObject<JavaFileObject> 
{
	// A delegating Writer that passes all commands to its contained Writer,
	// but hooks close() to notify the annotation dispatch manager of the new unit.
	private class ForwardingWriter extends Writer {
		private final Writer _w;
		ForwardingWriter(Writer w) {
			_w = w;
		}
		@Override
		public Writer append(char c) throws IOException {
			return _w.append(c);
		}
		@Override
		public Writer append(CharSequence csq, int start, int end)
				throws IOException {
			return _w.append(csq, start, end);
		}
		@Override
		public Writer append(CharSequence csq) throws IOException {
			return _w.append(csq);
		}
		// This is the only interesting method - it has to notify the
		// dispatch manager of the new file.
		@Override
		public void close() throws IOException {
			_w.close();
			closed();
		}
		@Override
		public void flush() throws IOException {
			_w.flush();
		}
		@Override
		public void write(char[] cbuf) throws IOException {
			_w.write(cbuf);
		}
		@Override
		public void write(int c) throws IOException {
			_w.write(c);
		}
		@Override
		public void write(String str, int off, int len)
				throws IOException {
			_w.write(str, off, len);
		}
		@Override
		public void write(String str) throws IOException {
			_w.write(str);
		}
		@Override
		public void write(char[] cbuf, int off, int len)
		throws IOException {
			_w.write(cbuf, off, len);
		}
		@Override
		protected Object clone() throws CloneNotSupportedException {
			return new ForwardingWriter(this._w);
		}
		@Override
		public int hashCode() {
			return _w.hashCode();
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			final ForwardingWriter other = (ForwardingWriter) obj;
			if (_w == null) {
				if (other._w != null)
					return false;
			} else if (!_w.equals(other._w))
				return false;
			return true;
		}
		@Override
		public String toString() {
			return "ForwardingWriter wrapping " + _w.toString(); //$NON-NLS-1$
		}
	}
	
	// A delegating Writer that passes all commands to its contained Writer,
	// but hooks close() to notify the annotation dispatch manager of the new unit.
	private class ForwardingOutputStream extends OutputStream {
		private final OutputStream _os;
		
		ForwardingOutputStream(OutputStream os) {
			_os = os;
		}
		
		@Override
		public void close() throws IOException {
			_os.close();
			closed();
		}
		@Override
		public void flush() throws IOException {
			_os.flush();
		}
		@Override
		public void write(byte[] b, int off, int len) throws IOException {
			_os.write(b, off, len);
		}
		@Override
		public void write(byte[] b) throws IOException {
			_os.write(b);
		}
		@Override
		public void write(int b) throws IOException {
			_os.write(b);
		}
		@Override
		protected Object clone() throws CloneNotSupportedException {
			return new ForwardingOutputStream(this._os);
		}
		@Override
		public int hashCode() {
			return _os.hashCode();
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			final ForwardingOutputStream other = (ForwardingOutputStream) obj;
			if (_os == null) {
				if (other._os != null)
					return false;
			} else if (!_os.equals(other._os))
				return false;
			return true;
		}
		@Override
		public String toString() {
			return "ForwardingOutputStream wrapping " + _os.toString(); //$NON-NLS-1$
		}
	}
	
	/**
	 * The Filer implementation that we need to notify when a new file is created. 
	 */
	protected final BatchFilerImpl _filer;
	
	/**
	 * The name of the file that is created; this is passed to the CompilationUnit constructor,
	 * and ultimately to the java.io.File constructor, so it is a normal pathname, just like 
	 * what would be on the compiler command line.
	 */
	protected final String _fileName;
	
	
	
	/**
	 * A compilation unit is created when the writer or stream is closed.  Only do this once.
	 */
	private boolean _closed = false;

	private String _typeName;
	
	public HookedJavaFileObject(JavaFileObject fileObject, String fileName, String typeName, BatchFilerImpl filer) {
		super(fileObject);
		_filer = filer;
		_fileName = fileName;
		_typeName = typeName;
	}

	@Override
	public OutputStream openOutputStream() throws IOException {
		return new ForwardingOutputStream(super.openOutputStream());
	}

	@Override
	public Writer openWriter() throws IOException {
		return new ForwardingWriter(super.openWriter());
	}
	
	protected void closed() {
		if (!_closed) {
			_closed = true;
			//TODO: support encoding
			switch(this.getKind()) {
				case SOURCE :
					CompilationUnit unit = new CompilationUnit(null, _fileName, null /* encoding */);
					_filer.addNewUnit(unit);
					break;
				case CLASS :
					IBinaryType binaryType = null;
					try {
						binaryType = ClassFileReader.read(_fileName);
					} catch (ClassFormatException e) {
						/* When the annotation processor produces garbage, javac seems to show some resilience, by hooking the source type,
						   which since is resolved can answer annotations during discovery - Not sure if this sanctioned by the spec, to be taken
						   up with Oracle. Here we mimic the bug, see that addNewClassFile is simply collecting ReferenceBinding's, so adding
						   a SourceTypeBinding works just fine.
						*/
						ReferenceBinding type = this._filer._env._compiler.lookupEnvironment.getType(CharOperation.splitOn('.', _typeName.toCharArray()));
						if (type != null) 
							_filer.addNewClassFile(type);
					} catch (IOException e) {
						// ignore
					}
					if (binaryType != null) {
						char[] name = binaryType.getName();
						ReferenceBinding type = this._filer._env._compiler.lookupEnvironment.getType(CharOperation.splitOn('/', name));
						if (type != null && type.isValidBinding()) {
							if (type.isBinaryBinding()) {
								_filer.addNewClassFile(type);
							} else {
								BinaryTypeBinding binaryBinding = new BinaryTypeBinding(type.getPackage(), binaryType, this._filer._env._compiler.lookupEnvironment, true);
								if (binaryBinding != null)
									_filer.addNewClassFile(binaryBinding);
							}
						}
					}
					break;
				case HTML:
				case OTHER:
					break;
			}
		}
	}
}
