/*******************************************************************************
 * Copyright (c) 2010, 2017 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.osgi.internal.weaving;

import java.security.*;
import java.util.*;
import org.eclipse.osgi.container.ModuleRevision;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.permadmin.BundlePermissions;
import org.eclipse.osgi.internal.serviceregistry.HookContext;
import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.StorageUtil;
import org.eclipse.osgi.storage.bundlefile.BundleEntry;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.*;
import org.osgi.framework.hooks.weaving.*;
import org.osgi.framework.wiring.BundleWiring;

public final class WovenClassImpl implements WovenClass, HookContext {
	private final static byte FLAG_HOOKCALLED = 0x01;
	private final static byte FLAG_HOOKSCOMPLETE = 0x02;
	private final static byte FLAG_WEAVINGCOMPLETE = 0x04;
	private final static String weavingHookName = WeavingHook.class.getName();
	private final String className;
	private final BundleEntry entry;
	private final List<String> dynamicImports;
	private final ClasspathEntry classpathEntry;
	private final BundleLoader loader;
	final ServiceRegistry registry;
	private final Map<ServiceRegistration<?>, Boolean> blackList;
	private byte[] validBytes;
	private byte[] resultBytes;
	private byte hookFlags = 0;
	private Throwable error;
	private ServiceRegistration<?> errorHook;
	private Class<?> clazz;
	private int state;
	final EquinoxContainer container;

	public WovenClassImpl(String className, byte[] bytes, BundleEntry entry, ClasspathEntry classpathEntry, BundleLoader loader, EquinoxContainer container, Map<ServiceRegistration<?>, Boolean> blacklist) {
		super();
		this.className = className;
		this.validBytes = this.resultBytes = bytes;
		this.entry = entry;
		this.dynamicImports = new DynamicImportList(this);
		this.classpathEntry = classpathEntry;
		this.loader = loader;
		this.registry = container.getServiceRegistry();
		this.container = container;
		this.blackList = blacklist;
		setState(TRANSFORMING);
	}

	public byte[] getBytes() {
		if ((hookFlags & FLAG_HOOKSCOMPLETE) == 0) {
			checkPermission();
			return validBytes; // return raw bytes until complete
		}
		// we have called all hooks; someone is calling outside of weave call
		// need to be safe and copy the bytes.
		byte[] current = validBytes;
		byte[] results = new byte[current.length];
		System.arraycopy(current, 0, results, 0, current.length);
		return results;
	}

	public void setBytes(byte[] newBytes) {
		checkPermission();
		if (newBytes == null)
			throw new NullPointerException("newBytes cannot be null."); //$NON-NLS-1$
		if ((hookFlags & FLAG_HOOKSCOMPLETE) != 0)
			// someone is calling this outside of weave
			throw new IllegalStateException("Weaving has completed already."); //$NON-NLS-1$
		this.resultBytes = this.validBytes = newBytes;
	}

	void checkPermission() {
		SecurityManager sm = System.getSecurityManager();
		if (sm != null)
			sm.checkPermission(new AdminPermission(loader.getWiring().getBundle(), AdminPermission.WEAVE));
	}

	public List<String> getDynamicImports() {
		if ((hookFlags & FLAG_HOOKSCOMPLETE) == 0)
			return dynamicImports;
		// being called outside of weave; return unmodified list
		return Collections.unmodifiableList(dynamicImports);
	}

	public boolean isWeavingComplete() {
		return (hookFlags & FLAG_WEAVINGCOMPLETE) != 0;
	}

	private void setHooksComplete() {
		// create a copy of the bytes array that noone has a reference to
		byte[] original = validBytes;
		validBytes = new byte[original.length];
		System.arraycopy(original, 0, validBytes, 0, original.length);
		hookFlags |= FLAG_HOOKSCOMPLETE;
	}

	void setWeavingCompleted(Class<?> clazz) {
		// weaving has completed; save the class and mark complete
		this.clazz = clazz;
		hookFlags |= FLAG_WEAVINGCOMPLETE;
		// Only notify listeners if weaving hooks were called.
		if ((hookFlags & FLAG_HOOKCALLED) == 0)
			return;
		// Only notify listeners if they haven't already been notified of
		// the terminal TRANSFORMING_FAILED state.
		if (error != null)
			return;
		// If clazz is null, a class definition failure occurred.
		setState(clazz == null ? DEFINE_FAILED : DEFINED);
		notifyWovenClassListeners();
	}

	public String getClassName() {
		return className;
	}

	public ProtectionDomain getProtectionDomain() {
		return classpathEntry.getDomain();
	}

	public Class<?> getDefinedClass() {
		return clazz;
	}

	public BundleWiring getBundleWiring() {
		return loader.getWiring();
	}

	public void call(final Object hook, ServiceRegistration<?> hookRegistration) throws Exception {
		if (error != null)
			return; // do not call any other hooks once an error has occurred.
		if (hook instanceof WeavingHook) {
			if (skipRegistration(hookRegistration)) {
				// Note we double check blacklist here just
				// in case another thread blacklisted since the first check
				return;
			}
			if ((hookFlags & FLAG_HOOKCALLED) == 0) {
				hookFlags |= FLAG_HOOKCALLED;
				// only do this check on the first weaving hook call
				if (!validBytes(validBytes)) {
					validBytes = StorageUtil.getBytes(entry.getInputStream(), (int) entry.getSize(), 8 * 1024);
				}
			}
			try {
				((WeavingHook) hook).weave(this);
			} catch (WeavingException e) {
				error = e;
				errorHook = hookRegistration;
				// do not blacklist on weaving exceptions
			} catch (Throwable t) {
				error = t; // save the error to fail later
				errorHook = hookRegistration;
				// put the registration on the black list
				blackList.put(hookRegistration, Boolean.TRUE);
			}
		}
	}

	@Override
	public boolean skipRegistration(ServiceRegistration<?> hookRegistration) {
		return blackList.containsKey(hookRegistration);
	}

	private boolean validBytes(byte[] checkBytes) {
		if (checkBytes == null || checkBytes.length < 4)
			return false;
		if ((checkBytes[0] & 0xCA) != 0xCA)
			return false;
		if ((checkBytes[1] & 0xFE) != 0xFE)
			return false;
		if ((checkBytes[2] & 0xBA) != 0xBA)
			return false;
		if ((checkBytes[3] & 0xBE) != 0xBE)
			return false;
		return true;
	}

	public String getHookMethodName() {
		return "weave"; //$NON-NLS-1$
	}

	public String getHookClassName() {
		return weavingHookName;
	}

	private void notifyWovenClassListeners() {
		final HookContext context = new HookContext() {
			@Override
			public void call(Object hook, ServiceRegistration<?> hookRegistration) throws Exception {
				if (!(hook instanceof WovenClassListener))
					return;
				try {
					((WovenClassListener) hook).modified(WovenClassImpl.this);
				} catch (Exception e) {
					WovenClassImpl.this.container.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hookRegistration.getReference().getBundle(), e);
				}
			}

			@Override
			public String getHookClassName() {
				return WovenClassListener.class.getName();
			}

			@Override
			public String getHookMethodName() {
				return "modified"; //$NON-NLS-1$
			}

			@Override
			public boolean skipRegistration(ServiceRegistration<?> hookRegistration) {
				return false;
			}
		};
		if (System.getSecurityManager() == null)
			registry.notifyHooksPrivileged(context);
		else {
			try {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
					public Void run() {
						registry.notifyHooksPrivileged(context);
						return null;
					}
				});
			} catch (PrivilegedActionException e) {
				throw (RuntimeException) e.getException();
			}
		}
	}

	byte[] callHooks() throws Throwable {
		SecurityManager sm = System.getSecurityManager();
		byte[] wovenBytes = null;
		List<String> newImports = null;
		boolean rejected = false;
		try {
			if (sm == null) {
				registry.notifyHooksPrivileged(this);
			} else {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
						public Void run() {
							registry.notifyHooksPrivileged(WovenClassImpl.this);
							return null;
						}
					});
				} catch (PrivilegedActionException e) {
					throw (RuntimeException) e.getException();
				}
			}
		} finally {
			if ((hookFlags & FLAG_HOOKCALLED) != 0) {
				for (ClassLoaderHook classLoaderHook : container.getConfiguration().getHookRegistry().getClassLoaderHooks()) {
					rejected |= classLoaderHook.rejectTransformation(className, resultBytes, classpathEntry, entry, loader.getModuleClassLoader().getClasspathManager());
				}
				if (!rejected) {
					wovenBytes = resultBytes;
					newImports = dynamicImports;
				}
				setHooksComplete();
				// Make sure setHooksComplete() has been called. The woven class
				// must be immutable in TRANSFORMED or TRANSFORMING_FAILED.
				// If error is not null, a weaving hook threw an exception.
				setState(error == null ? TRANSFORMED : TRANSFORMING_FAILED);
				// only notify listeners if the transformation was not rejected
				if (!rejected) {
					notifyWovenClassListeners();
				}
			}
		}

		if (error != null)
			throw error;

		if (newImports != null) {
			// add any new dynamic imports
			for (String newImport : newImports) {
				try {
					ManifestElement[] importElements = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, newImport);
					// Grant implied import package permissions for all dynamic
					// import packages to the woven bundle.
					addImpliedImportPackagePermissions(importElements);
					loader.addDynamicImportPackage(importElements);
				} catch (BundleException e) {
					// should not have happened; checked at add.
				}
			}
		}

		return wovenBytes;
	}

	private void addImpliedImportPackagePermissions(ManifestElement[] importElements) {
		ProtectionDomain wovenDomain = ((Generation) ((ModuleRevision) getBundleWiring().getRevision()).getRevisionInfo()).getDomain();
		if (wovenDomain != null) {
			// security is enabled; add the permissions
			for (ManifestElement clause : importElements)
				for (String pkg : clause.getValueComponents())
					((BundlePermissions) wovenDomain.getPermissions()).addWovenPermission(new PackagePermission(pkg, PackagePermission.IMPORT));
		}
	}

	public String toString() {
		return className;
	}

	public ServiceRegistration<?> getErrorHook() {
		return errorHook;
	}

	@Override
	public int getState() {
		return state;
	}

	private void setState(int value) {
		state = value;
	}
}
