/*******************************************************************************
 * Copyright (c) 2005, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.metatype.impl;

import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import javax.xml.parsers.*;
import org.eclipse.equinox.metatype.EquinoxMetaTypeInformation;
import org.eclipse.equinox.metatype.EquinoxMetaTypeService;
import org.eclipse.equinox.metatype.impl.Persistence.Reader;
import org.eclipse.equinox.metatype.impl.Persistence.Writer;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.service.metatype.MetaTypeInformation;
import org.osgi.util.tracker.ServiceTracker;
import org.xml.sax.SAXException;

/**
 * Implementation of MetaTypeService
 */
public class MetaTypeServiceImpl implements EquinoxMetaTypeService, SynchronousBundleListener {
	private static String CACHE_FILE = "metaTypeCache"; //$NON-NLS-1$
	SAXParserFactory _parserFactory;
	private Hashtable<Long, EquinoxMetaTypeInformation> _mtps = new Hashtable<Long, EquinoxMetaTypeInformation>(7);

	private final LogTracker logger;
	private final ServiceTracker<Object, Object> metaTypeProviderTracker;

	/**
	 * Constructor of class MetaTypeServiceImpl.
	 */
	public MetaTypeServiceImpl(SAXParserFactory parserFactory, LogTracker logger, ServiceTracker<Object, Object> metaTypeProviderTracker) {
		this._parserFactory = parserFactory;
		this.logger = logger;
		this.metaTypeProviderTracker = metaTypeProviderTracker;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.osgi.service.metatype.MetaTypeService#getMetaTypeInformation(org.osgi.framework.Bundle)
	 */
	public EquinoxMetaTypeInformation getMetaTypeInformation(Bundle bundle) {
		return getMetaTypeProvider(bundle);
	}

	/**
	 * Internal Method - to get MetaTypeProvider object.
	 */
	private EquinoxMetaTypeInformation getMetaTypeProvider(final Bundle b) {
		// Avoid synthetic accessor method warnings.
		final LogTracker loggerTemp = this.logger;
		final ServiceTracker<Object, Object> tracker = this.metaTypeProviderTracker;
		Long bID = Long.valueOf(b.getBundleId());
		synchronized (_mtps) {
			if (_mtps.containsKey(bID))
				return _mtps.get(bID);
			EquinoxMetaTypeInformation mti = AccessController.doPrivileged(new PrivilegedAction<EquinoxMetaTypeInformation>() {
				public EquinoxMetaTypeInformation run() {
					MetaTypeInformationImpl impl = null;
					try {
						impl = new MetaTypeInformationImpl(b, newParser(), loggerTemp);
					} catch (Exception e) {
						loggerTemp.log(LogTracker.LOG_ERROR, NLS.bind(MetaTypeMsg.METADATA_PARSE_ERROR, b.getBundleId(), b.getSymbolicName()), e);
					}
					if (impl == null || !impl._isThereMeta)
						return new MetaTypeProviderTracker(b, loggerTemp, tracker);
					return impl;
				}
			});
			_mtps.put(bID, mti);
			return mti;
		}
	}

	SAXParser newParser() throws ParserConfigurationException, SAXException {
		boolean namespaceAware = _parserFactory.isNamespaceAware();
		boolean validating = _parserFactory.isValidating();
		// Always want a non-validating parser.
		_parserFactory.setValidating(false);
		try {
			// If the factory is already namespace aware, we know it can create namespace aware parsers
			// because that was checked in the service tracker.
			if (namespaceAware) {
				return _parserFactory.newSAXParser();
			}
			// If the factory is not already namespace aware, it may or may not be able to create
			// namespace aware parsers.
			_parserFactory.setNamespaceAware(true);
			try {
				return _parserFactory.newSAXParser();
			} catch (Exception e) {
				// Factory cannot create namespace aware parsers. Go with the last resort.
				_parserFactory.setNamespaceAware(false);
				return _parserFactory.newSAXParser();
			}
		} finally {
			// Restore the previous settings in all cases.
			_parserFactory.setNamespaceAware(namespaceAware);
			_parserFactory.setValidating(validating);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
	 */
	public void bundleChanged(BundleEvent event) {

		int type = event.getType();
		Long bID = Long.valueOf(event.getBundle().getBundleId());

		switch (type) {
			case BundleEvent.UPDATED :
			case BundleEvent.UNINSTALLED :
				_mtps.remove(bID);
				break;
			case BundleEvent.INSTALLED :
			case BundleEvent.RESOLVED :
			case BundleEvent.STARTED :
			case BundleEvent.STOPPED :
			case BundleEvent.UNRESOLVED :
			default :
				break;
		}
	}

	void load(BundleContext context, LogTracker log, ServiceTracker<Object, Object> tracker) throws IOException {
		File cache = context.getDataFile(CACHE_FILE);
		// using system context to see all bundles by the ID
		BundleContext systemContext = context.getBundle(Constants.SYSTEM_BUNDLE_LOCATION).getBundleContext();
		if (cache.isFile()) {
			try (Reader reader = new Reader(new DataInputStream(new BufferedInputStream(new FileInputStream(cache))))) {

				int numService = reader.readInt();
				for (int i = 0; i < numService; i++) {
					long id = reader.readLong();
					Bundle b = systemContext.getBundle(id);
					if (b != null) {
						_mtps.put(b.getBundleId(), new MetaTypeProviderTracker(b, log, tracker));
					}
				}

				reader.readIndexedStrings();

				int numXML = reader.readInt();
				for (int i = 0; i < numXML; i++) {
					MetaTypeInformationImpl info = MetaTypeInformationImpl.load(systemContext, log, reader);
					if (info != null) {
						_mtps.put(info.getBundle().getBundleId(), info);
					}
				}
			}
		}
	}

	void save(BundleContext context) throws IOException {
		File cache = context.getDataFile(CACHE_FILE);
		try (Writer writer = new Writer(new DataOutputStream(new BufferedOutputStream(new FileOutputStream(cache))))) {
			List<MetaTypeInformation> serviceInfos = new ArrayList<>();
			List<MetaTypeInformationImpl> xmlInfos = new ArrayList<>();
			synchronized (_mtps) {
				for (MetaTypeInformation info : _mtps.values()) {
					if (info instanceof MetaTypeInformationImpl) {
						xmlInfos.add((MetaTypeInformationImpl) info);
					} else {
						serviceInfos.add(info);
					}
				}
			}

			writer.writeInt(serviceInfos.size());
			for (MetaTypeInformation info : serviceInfos) {
				writer.writeLong(info.getBundle().getBundleId());
			}

			Set<String> strings = new HashSet<>();
			for (MetaTypeInformationImpl info : xmlInfos) {
				info.getStrings(strings);
			}
			writer.writeIndexedStrings(strings);

			writer.writeInt(xmlInfos.size());
			for (MetaTypeInformationImpl info : xmlInfos) {
				info.write(writer);
			}
		}
	}
}
