/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Francis Lynch (Wind River) - [305718] Allow reading snapshot into renamed project
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427
 *******************************************************************************/
package org.eclipse.core.internal.resources;

import java.io.*;
import java.util.*;
import org.eclipse.core.internal.events.BuilderPersistentInfo;
import org.eclipse.core.internal.utils.Messages;
import org.eclipse.core.internal.utils.Policy;
import org.eclipse.core.internal.watson.ElementTree;
import org.eclipse.core.internal.watson.ElementTreeReader;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.runtime.*;

/**
 * Reads version 1 of the workspace tree file format.
 */
public class WorkspaceTreeReader_1 extends WorkspaceTreeReader {
	protected Workspace workspace;

	public WorkspaceTreeReader_1(Workspace workspace) {
		this.workspace = workspace;
	}

	protected int getVersion() {
		return ICoreConstants.WORKSPACE_TREE_VERSION_1;
	}

	protected void linkBuildersToTrees(List<BuilderPersistentInfo> buildersToBeLinked, ElementTree[] trees, int index, IProgressMonitor monitor) {
		monitor = Policy.monitorFor(monitor);
		try {
			ArrayList<BuilderPersistentInfo> infos = null;
			String projectName = null;
			for (int i = 0; i < buildersToBeLinked.size(); i++) {
				BuilderPersistentInfo info = buildersToBeLinked.get(i);
				if (!info.getProjectName().equals(projectName)) {
					if (infos != null) { // if it is not the first iteration
						IProject project = workspace.getRoot().getProject(projectName);
						workspace.getBuildManager().setBuildersPersistentInfo(project, infos);
					}
					projectName = info.getProjectName();
					infos = new ArrayList<>(5);
				}
				info.setLastBuildTree(trees[index++]);
				infos.add(info);
			}
			if (infos != null) {
				IProject project = workspace.getRoot().getProject(projectName);
				workspace.getBuildManager().setBuildersPersistentInfo(project, infos);
			}
		} finally {
			monitor.done();
		}
	}

	protected void linkPluginsSavedStateToTrees(List<SavedState> states, ElementTree[] trees, IProgressMonitor monitor) {
		monitor = Policy.monitorFor(monitor);
		try {
			for (int i = 0; i < states.size(); i++) {
				SavedState state = states.get(i);
				// If the tree is too old (depends on the policy), the plug-in should not
				// get it back as a delta. It is expensive to maintain this information too long.
				final SaveManager saveManager = workspace.getSaveManager();
				if (!saveManager.isOldPluginTree(state.pluginId)) {
					state.oldTree = trees[i];
				} else {
					//clear information for this plugin from master table
					saveManager.clearDeltaExpiration(state.pluginId);
				}
			}
		} finally {
			monitor.done();
		}
	}

	protected BuilderPersistentInfo readBuilderInfo(IProject project, DataInputStream input, int index) throws IOException {
		//read the project name
		String projectName = input.readUTF();
		//use the name of the project handle if available
		if (project != null)
			projectName = project.getName();
		String builderName = input.readUTF();
		return new BuilderPersistentInfo(projectName, builderName, index);
	}

	protected void readBuildersPersistentInfo(IProject project, DataInputStream input, List<BuilderPersistentInfo> builders, IProgressMonitor monitor) throws IOException {
		monitor = Policy.monitorFor(monitor);
		try {
			int builderCount = input.readInt();
			for (int i = 0; i < builderCount; i++)
				builders.add(readBuilderInfo(project, input, i));
		} finally {
			monitor.done();
		}
	}

	protected void readPluginsSavedStates(DataInputStream input, HashMap<String, SavedState> savedStates, List<SavedState> plugins, IProgressMonitor monitor) throws IOException, CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			int stateCount = input.readInt();
			for (int i = 0; i < stateCount; i++) {
				String pluginId = input.readUTF();
				SavedState state = new SavedState(workspace, pluginId, null, null);
				savedStates.put(pluginId, state);
				plugins.add(state);
			}
		} finally {
			monitor.done();
		}
	}

	@Override
	public ElementTree readSnapshotTree(DataInputStream input, ElementTree complete, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		String message;
		try {
			message = Messages.resources_readingSnap;
			monitor.beginTask(message, Policy.totalWork);
			ElementTreeReader reader = new ElementTreeReader(workspace.getSaveManager());
			while (input.available() > 0) {
				readWorkspaceFields(input, Policy.subMonitorFor(monitor, Policy.totalWork / 2));
				complete = reader.readDelta(complete, input);
				try {
					// make sure each snapshot is read by the correct reader
					int version = input.readInt();
					if (version != getVersion())
						return WorkspaceTreeReader.getReader(workspace, version).readSnapshotTree(input, complete, monitor);
				} catch (EOFException e) {
					break;
				}
			}
			return complete;
		} catch (IOException e) {
			message = Messages.resources_readWorkspaceSnap;
			throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, null, message, e);
		} finally {
			monitor.done();
		}
	}

	@Override
	public void readTree(DataInputStream input, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		String message;
		try {
			message = Messages.resources_reading;
			monitor.beginTask(message, Policy.totalWork);
			readWorkspaceFields(input, Policy.subMonitorFor(monitor, Policy.opWork * 20 / 100));

			HashMap<String, SavedState> savedStates = new HashMap<>(20);
			List<SavedState> pluginsToBeLinked = new ArrayList<>(20);
			readPluginsSavedStates(input, savedStates, pluginsToBeLinked, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100));
			workspace.getSaveManager().setPluginsSavedState(savedStates);

			List<BuilderPersistentInfo> buildersToBeLinked = new ArrayList<>(20);
			readBuildersPersistentInfo(null, input, buildersToBeLinked, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100));

			ElementTree[] trees = readTrees(Path.ROOT, input, Policy.subMonitorFor(monitor, Policy.opWork * 40 / 100));
			linkPluginsSavedStateToTrees(pluginsToBeLinked, trees, Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100));
			linkBuildersToTrees(buildersToBeLinked, trees, pluginsToBeLinked.size(), Policy.subMonitorFor(monitor, Policy.opWork * 10 / 100));

		} catch (IOException e) {
			message = Messages.resources_readWorkspaceTree;
			throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, null, message, e);
		} finally {
			monitor.done();
		}
	}

	@Override
	public void readTree(IProject project, DataInputStream input, IProgressMonitor monitor) throws CoreException {
		monitor = Policy.monitorFor(monitor);
		String message;
		try {
			message = Messages.resources_reading;
			monitor.beginTask(message, 10);
			/* read the number of builders */
			int numBuilders = input.readInt();

			/* read in the list of builder names */
			String[] builderNames = new String[numBuilders];
			for (int i = 0; i < numBuilders; i++) {
				String builderName = input.readUTF();
				builderNames[i] = builderName;
			}
			monitor.worked(1);

			/* read and link the trees */
			ElementTree[] trees = readTrees(project.getFullPath(), input, Policy.subMonitorFor(monitor, 8));

			/* map builder names to trees */
			if (numBuilders > 0) {
				ArrayList<BuilderPersistentInfo> infos = new ArrayList<>(trees.length * 2 + 1);
				for (int i = 0; i < numBuilders; i++) {
					BuilderPersistentInfo info = new BuilderPersistentInfo(project.getName(), builderNames[i], -1);
					info.setLastBuildTree(trees[i]);
					infos.add(info);
				}
				workspace.getBuildManager().setBuildersPersistentInfo(project, infos);
			}
			monitor.worked(1);

		} catch (IOException e) {
			message = Messages.resources_readProjectTree;
			throw new ResourceException(IResourceStatus.FAILED_READ_METADATA, null, message, e);
		} finally {
			monitor.done();
		}
	}

	/**
	 * Read trees from disk and link them to the workspace tree.
	 */
	protected ElementTree[] readTrees(IPath root, DataInputStream input, IProgressMonitor monitor) throws IOException {
		monitor = Policy.monitorFor(monitor);
		try {
			String message = Messages.resources_reading;
			monitor.beginTask(message, 4);
			ElementTreeReader treeReader = new ElementTreeReader(workspace.getSaveManager());
			String newProjectName = ""; //$NON-NLS-1$
			if (renameProjectNode) {
				//have the existing project name (path to import into) take precedence over what we read
				newProjectName = root.segment(0);
			}
			ElementTree[] trees = treeReader.readDeltaChain(input, newProjectName);
			monitor.worked(3);
			if (root.isRoot()) {
				//Don't need to link because we're reading the whole workspace.
				//The last tree in the chain is the complete tree.
				ElementTree newTree = trees[trees.length - 1];
				newTree.setTreeData(workspace.tree.getTreeData());
				workspace.tree = newTree;
			} else {
				//splice the restored tree into the current set of trees
				workspace.linkTrees(root, trees);
			}
			monitor.worked(1);
			return trees;
		} finally {
			monitor.done();
		}
	}

	protected void readWorkspaceFields(DataInputStream input, IProgressMonitor monitor) throws IOException, CoreException {
		monitor = Policy.monitorFor(monitor);
		try {
			// read the node id
			workspace.nextNodeId = input.readLong();
			// read the modification stamp (no longer used)
			input.readLong();
			// read the next marker id
			workspace.nextMarkerId = input.readLong();
			// read the synchronizer's registered sync partners
			((Synchronizer) workspace.getSynchronizer()).readPartners(input);
		} finally {
			monitor.done();
		}
	}
}
