/*******************************************************************************
 *  Copyright (c) 2000, 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
 *  Martin Oberhuber (Wind River) - [306573] Add tests for import from snapshot
 *******************************************************************************/
package org.eclipse.core.tests.resources.perf;

import java.io.ByteArrayInputStream;
import java.net.URI;
import java.util.Random;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.tests.harness.PerformanceTestRunner;
import org.eclipse.core.tests.resources.ResourceTest;

/**
 * Basic performance calculations for standard workspace operations.
 */
public class WorkspacePerformanceTest extends ResourceTest {
	private static final String chars = "abcdefghijklmnopqrstuvwxyz";
	static final int REPEATS = 5;
	private static final int TREE_WIDTH = 10;
	private static final int DEFAULT_TOTAL_RESOURCES = 10000;

	private final Random random = new Random();
	IFolder testFolder;
	IProject testProject;

	public static Test suite() {
		return new TestSuite(WorkspacePerformanceTest.class);
		//		TestSuite suite = new TestSuite();
		//		suite.addTest(new WorkspacePerformanceTest("testRefreshProject"));
		//		return suite;
	}

	public WorkspacePerformanceTest() {
		super();
	}

	public WorkspacePerformanceTest(String name) {
		super(name);
	}

	IFolder copyFolder() {
		IFolder destination = testProject.getFolder("CopyDestination");
		try {
			testFolder.copy(destination.getFullPath(), IResource.NONE, getMonitor());
		} catch (CoreException e) {
			fail("Failed to copy project in performance test", e);
		}
		return destination;
	}

	/**
	 * Creates a project and fills it with contents
	 */
	void createAndPopulateProject(final int totalResources) {
		try {
			getWorkspace().run((IWorkspaceRunnable) monitor -> {
				testProject.create(getMonitor());
				testProject.open(getMonitor());
				createFolder(testFolder, totalResources);
			}, getMonitor());
		} catch (CoreException e) {
			fail("Failed to create project in performance test", e);
		}
	}

	private byte[] createBytes(int length) {
		byte[] bytes = new byte[length];
		random.nextBytes(bytes);
		return bytes;
	}

	/**
	 * Creates and returns a folder with lots of contents
	 */
	IFolder createFolder(IFolder topFolder, int totalResources) throws CoreException {
		topFolder.create(IResource.NONE, true, getMonitor());
		//tree depth is log of total resource count with the width as the log base
		int depth = (int) (Math.log(totalResources) / Math.log(TREE_WIDTH));
		recursiveCreateChildren(topFolder, depth - 1);
		return topFolder;
	}

	private String createString(int length) {
		StringBuffer buf = new StringBuffer(length);
		//fill the string with random characters up to the desired length
		for (int i = 0; i < length; i++) {
			buf.append(chars.charAt(random.nextInt(chars.length())));
		}
		return buf.toString();
	}

	/**
	 * Deletes the test project without deleting content, and then recreates
	 * the project without discovering content on disk.  This sets us up
	 * for benchmarking performance of refresh local.
	 */
	void deleteAndRecreateProject() throws CoreException {
		//delete without deleting contents
		testProject.delete(IResource.NEVER_DELETE_PROJECT_CONTENT, null);
		//recreate project but don't discover content
		testProject.create(null);
		testProject.open(IResource.NONE, null);
	}

	IFolder moveFolder() {
		IFolder destination = testFolder.getProject().getFolder("MoveDestination");
		try {
			testFolder.move(destination.getFullPath(), IResource.NONE, getMonitor());
		} catch (CoreException e) {
			fail("Failed to move folder during performance test", e);
		}
		return destination;
	}

	/**
	 * Create children of the given folder, and recurse to the given depth
	 */
	private void recursiveCreateChildren(IFolder parentFolder, int depth) throws CoreException {
		//create TREE_WIDTH files
		for (int i = 0; i < TREE_WIDTH; i++) {
			IFile file = parentFolder.getFile(createString(10));
			file.create(new ByteArrayInputStream(createBytes(5000)), IResource.NONE, getMonitor());
		}
		if (depth <= 0) {
			return;
		}
		//create TREE_WIDTH folders
		for (int i = 0; i < TREE_WIDTH; i++) {
			IFolder folder = parentFolder.getFolder(createString(6));
			folder.create(IResource.NONE, true, getMonitor());
			recursiveCreateChildren(folder, depth - 1);
		}
	}

	@Override
	protected void setUp() throws Exception {
		testProject = getWorkspace().getRoot().getProject("Project");
		testFolder = testProject.getFolder("TopFolder");
	}

	/**
	 * Benchmark test of creating a project and populating it with folders and files.
	 */
	public void testCreateResources() {
		PerformanceTestRunner runner = new PerformanceTestRunner() {
			@Override
			protected void setUp() {
				waitForBackgroundActivity();
			}

			@Override
			protected void tearDown() throws CoreException {
				testProject.delete(IResource.FORCE, null);
			}

			@Override
			protected void test() {
				createAndPopulateProject(DEFAULT_TOTAL_RESOURCES);
			}
		};
		runner.run(this, REPEATS, 1);
	}

	public void testDeleteProject() {
		//create the project contents
		PerformanceTestRunner runner = new PerformanceTestRunner() {
			@Override
			protected void setUp() {
				createAndPopulateProject(DEFAULT_TOTAL_RESOURCES);
				waitForBackgroundActivity();
			}

			@Override
			protected void test() {
				try {
					testProject.delete(IResource.NONE, null);
				} catch (CoreException e) {
					fail("Failed to delete project during performance test", e);
				}
			}
		};
		runner.run(this, REPEATS, 1);
	}

	public void testFolderCopy() {
		//create the project contents
		new PerformanceTestRunner() {
			@Override
			protected void setUp() {
				createAndPopulateProject(DEFAULT_TOTAL_RESOURCES);
				waitForBackgroundActivity();
			}

			@Override
			protected void tearDown() throws CoreException {
				testProject.delete(IResource.FORCE, null);
			}

			@Override
			protected void test() {
				copyFolder();
			}
		}.run(this, REPEATS, 1);
	}

	public void testFolderMove() {
		//create the project contents
		new PerformanceTestRunner() {
			@Override
			protected void setUp() {
				createAndPopulateProject(DEFAULT_TOTAL_RESOURCES);
				waitForBackgroundActivity();
			}

			@Override
			protected void tearDown() throws CoreException {
				testProject.delete(IResource.FORCE, null);
			}

			@Override
			protected void test() {
				moveFolder();
			}
		}.run(this, REPEATS, 1);
	}

	public void testRefreshProject() {
		PerformanceTestRunner runner = new PerformanceTestRunner() {
			@Override
			protected void setUp() throws CoreException {
				createAndPopulateProject(50000);
				deleteAndRecreateProject();
				waitForBackgroundActivity();
			}

			@Override
			protected void tearDown() throws CoreException {
				testProject.delete(IResource.FORCE, null);
			}

			@Override
			protected void test() {
				try {
					testProject.refreshLocal(IResource.DEPTH_INFINITE, null);
				} catch (CoreException e) {
					fail("Failed to refresh during testRefreshProject", e);
				}
			}
		};
		runner.setFingerprintName("Refresh Project");
		runner.run(this, REPEATS, 1);
	}

	public void testCloseOpenProject() {
		// 8 minutes total test time, 400 msec test execution time (*3 inner loops)
		new PerformanceTestRunner() {
			@Override
			protected void setUp() {
				createAndPopulateProject(50000);
				waitForBackgroundActivity();
			}

			@Override
			protected void tearDown() throws CoreException {
				testProject.delete(IResource.FORCE, null);
			}

			@Override
			protected void test() {
				try {
					testProject.close(null);
					testProject.open(null);
				} catch (CoreException e) {
					fail("Failed to close/open during testCloseOpenProject", e);
				}
			}
		}.run(this, REPEATS, 3);
	}

	public void testLoadSnapshot() {
		// 2 minutes total test time, 528 msec test execution time
		IProject snapProject = getWorkspace().getRoot().getProject("SnapProject");
		ensureExistsInWorkspace(snapProject, true);
		final URI snapshotLocation = snapProject.getFile("snapshot.zip").getLocationURI();
		createAndPopulateProject(50000);
		waitForBackgroundActivity();
		try {
			testProject.saveSnapshot(IProject.SNAPSHOT_TREE, snapshotLocation, null);
			testProject.delete(IResource.FORCE, null);
		} catch (CoreException e) {
			fail("Failed to create snapshot during testLoadSnapshot");
		}
		waitForBackgroundActivity();
		new PerformanceTestRunner() {
			@Override
			protected void setUp() {
			}

			@Override
			protected void tearDown() throws CoreException {
				testProject.delete(IResource.FORCE, null);
			}

			@Override
			protected void test() {
				try {
					testProject.create(null);
					testProject.loadSnapshot(IProject.SNAPSHOT_TREE, snapshotLocation, null);
					testProject.open(null);
				} catch (CoreException e) {
					fail("Failed to load snapshot during testLoadSnapshot", e);
				}
			}
		}.run(this, REPEATS, 1);
	}

	/**
	 * Waits until background activity settles down before running a performance test.
	 *
	 */
	public void waitForBackgroundActivity() {
		waitForSnapshot();
		waitForRefresh();
		waitForBuild();
	}

	/**
	 * Wait for snapshot to complete by running and joining a workspace modification job.
	 * This job will get queued to run behind any scheduled snapshot job.
	 */
	private void waitForSnapshot() {
		Job wait = new Job("Wait") {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				return Status.OK_STATUS;
			}
		};
		wait.setRule(getWorkspace().getRoot());
		wait.schedule();
		try {
			wait.join();
		} catch (InterruptedException e) {
			//ignore interruption
		}
	}
}
