/*******************************************************************************
 * Copyright (c) 2013 SAP AG.
 * 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:
 *    Eduard Bartsch (SAP AG) - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.resources.semantic.test;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

import org.eclipse.core.internal.resources.semantic.SemanticMetadataPersistenceManager;
import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticDB;
import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.SemanticResourceDBFactory;
import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeNodeType;
import org.eclipse.core.internal.resources.semantic.model.SemanticResourceDB.TreeRoot;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * 
 */
public class TestMetadataPersistenceManager {
	private static final String TEST_ROOT = "testRoot";
	private static final String TEST_ROOT2 = "testRoot2";
	private File rootFolder;
	private SemanticMetadataPersistenceManager mgr;
	private SemanticMetadataPersistenceManager mgr2;
	private SemanticMetadataPersistenceManager mgr3;

	@Before
	public void beforeMethod() throws Exception {
		this.rootFolder = createTestRoot();
		mgr = new SemanticMetadataPersistenceManager(this.rootFolder);
		mgr2 = new SemanticMetadataPersistenceManager(this.rootFolder);
		mgr3 = new SemanticMetadataPersistenceManager(this.rootFolder);
	}

	@After
	public void afterMethod() throws Exception {
		deleteRecursively(this.rootFolder);
	}

	@Test
	public void test_GivenNoMetadataExists_WhenInitAndSave_ThenMetadataFileIsCreated() throws Exception {
		mgr.init();

		File metadataLocation = mgr.getMetadataFile(null);

		Assert.assertTrue(rootFolder.exists());
		Assert.assertFalse(metadataLocation.exists());

		mgr.saveSemanticDB(null);

		Assert.assertTrue("metadata file must be created", metadataLocation.exists());
	}

	@Test
	public void test_GivenNoMetadataExists_WhenInitAddOneExistingRootAndSaveAll_ThenTwoMetadataFileAreCreated() throws Exception {
		mgr.init();

		SemanticDB db = mgr.getSemanticDB();

		db.getRoots().add(createRootNode(TEST_ROOT, true));

		mgr.saveSemanticDB(null);

		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists());
		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT).exists());
	}

	@Test
	public void test_GivenNoMetadataExists_WhenInitAddTwoExistingRootsAndSaveAll_ThenThreeMetadataFileAreCreated() throws Exception {
		mgr.init();

		SemanticDB db = mgr.getSemanticDB();

		db.getRoots().add(createRootNode(TEST_ROOT, true));

		db.getRoots().add(createRootNode(TEST_ROOT2, true));

		mgr.saveSemanticDB(null);

		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists());
		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT).exists());
		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT2).exists());
	}

	@Test
	public void test_GivenNoMetadataExists_WhenInitAddTwoExistingRootsAndSaveOne_ThenTwoMetadataFileAreCreated() throws Exception {
		mgr.init();

		SemanticDB db = mgr.getSemanticDB();

		db.getRoots().add(createRootNode(TEST_ROOT, true));

		db.getRoots().add(createRootNode(TEST_ROOT2, true));

		mgr.saveSemanticDB(TEST_ROOT);

		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists());
		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(TEST_ROOT).exists());
		Assert.assertFalse("metadata file must not be created", mgr.getMetadataFile(TEST_ROOT2).exists());
	}

	@Test
	public void test_GivenOneRootExists_WhenInit_ThenOneRootIsPresent() throws Exception {
		// given
		mgr.init();
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true));
		mgr.saveSemanticDB(null);

		// when
		mgr2.init();

		// then
		SemanticDB db = mgr2.getSemanticDB();

		Assert.assertEquals(1, db.getRoots().size());
		Assert.assertEquals(TEST_ROOT, db.getRoots().get(0).getName());
	}

	@Test
	public void test_GivenTwoRootsExists_WhenLoadAndSaveOnlyOneRoot_ThenOnlyTwoMetadataFilesAreChanged() throws Exception {
		// given
		mgr.init();
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true));
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT2, true));
		mgr.saveSemanticDB(null);

		long lastModification = mgr.getMetadataFile(null).lastModified();
		long lastModification1 = mgr.getMetadataFile(TEST_ROOT).lastModified();
		long lastModification2 = mgr.getMetadataFile(TEST_ROOT2).lastModified();

		Thread.sleep(1011);

		// when
		mgr2.init();

		mgr2.saveSemanticDB(TEST_ROOT);

		// then
		long newModification = mgr2.getMetadataFile(null).lastModified();
		long newModification1 = mgr2.getMetadataFile(TEST_ROOT).lastModified();
		long newModification2 = mgr2.getMetadataFile(TEST_ROOT2).lastModified();

		Assert.assertTrue("metadata file must be modified", lastModification != newModification);
		Assert.assertTrue("metadata file must be modified", lastModification1 != newModification1);
		Assert.assertTrue("metadata file must not be modified", lastModification2 == newModification2);
	}

	@Test
	public void test_GivenTwoRootsExistsInOldMetadata_WhenLoadAndMigrate_ThenThreeMetadataFilesAreCreated() throws Exception {
		// given

		// use mgr.init() to create a folder that simulates metadata
		// content before migrations
		mgr.init();

		mgr2.initSemanticDB();
		mgr2.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true));
		mgr2.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT2, true));

		Assert.assertFalse("metadata file must not be created", mgr2.getMetadataFile(null).exists());
		Assert.assertFalse("metadata file must not be created", mgr2.getMetadataFile(TEST_ROOT).exists());
		Assert.assertFalse("metadata file must not be created", mgr2.getMetadataFile(TEST_ROOT2).exists());

		// when
		mgr2.migrateSemanticDB();

		// then
		Assert.assertTrue("metadata file must be created", mgr2.getMetadataFile(null).exists());
		Assert.assertTrue("metadata file must be created", mgr2.getMetadataFile(TEST_ROOT).exists());
		Assert.assertTrue("metadata file must be created", mgr2.getMetadataFile(TEST_ROOT2).exists());
	}

	@Test
	public void test_GivenOneRootExists_WhenSetRootNotExistsSaveAndLoad_ThenOneMetadataFileIsPresent() throws Exception {
		// given
		mgr.init();
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true));
		mgr.saveSemanticDB(null);

		// when
		SemanticDB db = mgr.getSemanticDB();

		TreeRoot root = db.getRoots().get(0);
		root.setExists(false);

		mgr.saveSemanticDB(null);

		mgr2.init();

		// then
		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists());
		Assert.assertFalse("metadata file must not be created", mgr.getMetadataFile(TEST_ROOT).exists());
	}

	@Test
	public void test_GivenOneRootExists_WhenRemoveRootSaveAndLoad_ThenOneMetadataFileIsPresent() throws Exception {
		// given
		mgr.init();
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true));
		mgr.saveSemanticDB(null);

		// when
		mgr.getSemanticDB().getRoots().remove(0);

		mgr.saveSemanticDB(null);

		mgr2.init();

		// then
		Assert.assertTrue("metadata file must be created", mgr.getMetadataFile(null).exists());
		Assert.assertFalse("metadata file must not be created", mgr.getMetadataFile(TEST_ROOT).exists());
	}

	@Test
	public void test_GivenTwoRootsExists_WhenRemoveRootSaveAndLoad_ThenOnlyTwoMetadataFilesArePresent() throws Exception {
		// given
		mgr.init();
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT, true));
		mgr.getSemanticDB().getRoots().add(createRootNode(TEST_ROOT2, true));
		mgr.saveSemanticDB(null);

		// when
		mgr2.init();

		mgr2.getSemanticDB().getRoots().remove(0);

		mgr2.saveSemanticDB(null);

		mgr3.init();

		// then
		Assert.assertTrue("metadata file must be created", mgr3.getMetadataFile(null).exists());
		Assert.assertFalse("metadata file must not be created", mgr3.getMetadataFile(TEST_ROOT).exists());
		Assert.assertTrue("metadata file must be created", mgr3.getMetadataFile(TEST_ROOT2).exists());

	}

	// Helper methods

	private TreeRoot createRootNode(String name, boolean exists) {
		TreeRoot root = SemanticResourceDBFactory.eINSTANCE.createTreeRoot();

		root.setName(name);
		root.setExists(exists);
		root.setPath("/" + name); //$NON-NLS-1$
		root.setType(TreeNodeType.PROJECT);

		return root;
	}

	private File createTestRoot() {
		String tmpdir = System.getProperty("java.io.tmpdir");
		String uuid = UUID.randomUUID().toString();
		File uniqueRoot = new File(tmpdir, uuid);
		uniqueRoot.deleteOnExit();
		return uniqueRoot;
	}

	private void deleteRecursively(File root) throws IOException {
		if (root.exists()) {
			if (root.isFile()) {
				root.delete();
			} else {
				File[] files = root.listFiles();
				if (files != null) {
					for (File file : files) {
						deleteRecursively(file);
					}
				}
				if (!root.delete()) {
					throw new IOException("Unable to delete " + root.getAbsolutePath());
				}
			}
		}
	}

}
