/*******************************************************************************
 * Copyright (c) 2003, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.internal.resolver;

import java.io.*;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.BundleException;

public class StateManager implements PlatformAdmin {
	public static boolean DEBUG = false;
	public static boolean DEBUG_READER = false;
	public static boolean DEBUG_PLATFORM_ADMIN = false;
	public static boolean DEBUG_PLATFORM_ADMIN_RESOLVER = false;
	public static boolean MONITOR_PLATFORM_ADMIN = false;
	private long readStartupTime;
	private StateImpl systemState;
	private File stateLocation;
	private StateObjectFactoryImpl factory;
	private long lastTimeStamp;
	private BundleInstaller installer;

	public StateManager(File stateLocation) {
		// a negative timestamp means no timestamp checking
		this(stateLocation, -1);
	}

	public StateManager(File stateLocation, long expectedTimeStamp) {
		factory = new StateObjectFactoryImpl();
		this.stateLocation = stateLocation;
		readState(expectedTimeStamp);
	}

	public void shutdown() throws IOException {
		writeState();
		//systemState should not be set to null as when the framework
		//is restarted from a shutdown state, the systemState variable will
		//not be reset, resulting in a null pointer exception
		//systemState = null;
	}

	private void readState(long expectedTimeStamp) {
		if (!stateLocation.isFile())
			return;
		if (DEBUG_READER)
			readStartupTime = System.currentTimeMillis();
		FileInputStream fileInput;
		try {
			fileInput = new FileInputStream(stateLocation);
		} catch (FileNotFoundException e) {
			// TODO: log before bailing
			e.printStackTrace();
			return;
		}
		DataInputStream input = null;
		try {
			input = new DataInputStream(new BufferedInputStream(fileInput, 65536));
			systemState = factory.readSystemState(input, expectedTimeStamp);
			// problems in the cache (corrupted/stale), don't create a state object
			if (systemState == null)
				return;
			initializeSystemState();
		} catch (IOException ioe) {
			// TODO: how do we log this?
			ioe.printStackTrace();
		} finally {
			if (DEBUG_READER)
				System.out.println("Time to read state: " + (System.currentTimeMillis() - readStartupTime));
		}
	}

	private void writeState() throws IOException {
		if (systemState == null)
			return;
		if (stateLocation.isFile() && lastTimeStamp == systemState.getTimeStamp())
			return;
		DataOutputStream output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(stateLocation)));
		factory.writeState(systemState, output);
	}

	public StateImpl createSystemState() {
		systemState = factory.createSystemState();
		initializeSystemState();
		return systemState;
	}

	private void initializeSystemState() {
		systemState.setResolver(new ResolverImpl());
		lastTimeStamp = systemState.getTimeStamp();
	}

	public StateImpl getSystemState() {
		return systemState;
	}

	public State getState(boolean mutable) {
		return mutable ? factory.createState(systemState) : new ReadOnlyState(systemState);
	}

	public State getState() {
		return getState(true);
	}

	public StateObjectFactory getFactory() {
		return factory;
	}

	public synchronized void commit(State state) throws BundleException {
		// client trying to sneak in some alien implementation
		if (!(state instanceof UserState))
			throw new IllegalArgumentException("Wrong state implementation"); //$NON-NLS-1$
		// no installer have been provided - commit not supported
		if (installer == null)
			throw new IllegalArgumentException("PlatformAdmin.commit() not supported"); //$NON-NLS-1$
		if (state.getTimeStamp() != systemState.getTimeStamp())
			throw new BundleException(StateMsg.formatter.getString("COMMIT_INVALID_TIMESTAMP")); //$NON-NLS-1$
		UserState userState = (UserState) state;
		Long[] allAdded = userState.getAllAdded();
		for (int i = 0; i < allAdded.length; i++) {
			BundleDescription added = userState.getBundle(allAdded[i].longValue());
			// ensure it has not been added then removed
			if (added != null)
				installer.installBundle(added);
		}
		Long[] allRemoved = userState.getAllRemoved();
		for (int i = 0; i < allRemoved.length; i++) {
			long removedId = allRemoved[i].longValue();
			BundleDescription removedFromUserState = userState.getBundle(removedId);
			// ensure it has not been removed then added
			if (removedFromUserState == null) {
				BundleDescription existingSystemState = systemState.getBundle(removedId);
				if (existingSystemState != null)
					installer.uninstallBundle(existingSystemState);
			}
		}
	}

	public Resolver getResolver() {
		return new ResolverImpl();
	}

	public StateHelper getStateHelper() {
		return StateHelperImpl.getInstance();
	}

	public File getStateLocation() {
		return stateLocation;
	}

	public BundleInstaller getInstaller() {
		return installer;
	}

	public void setInstaller(BundleInstaller installer) {
		this.installer = installer;
	}
}