/*******************************************************************************
 * Copyright (c) 2004, 2008 Tasktop Technologies 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:
 *     Jevgeni Holodkov - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.tasks.tests;

import junit.framework.TestCase;

/**
 * @author Jevgeni Holodkov
 */
// FIXME fix test
public class QueryExportImportTest extends TestCase {

	public void testRewriteTestCases() {
	}

//	private File dest;
//
//	private TaskListElementImporter taskListWriter;
//
//	@Override
//	protected void setUp() throws Exception {
//		removeFiles(new File(TasksUiPlugin.getDefault().getDataDirectory()));
//
//		// Create test export destination directory
//		dest = new File(TasksUiPlugin.getDefault().getDataDirectory() + File.separator + "TestDir");
//		if (dest.exists()) {
//			removeFiles(dest);
//		} else {
//			dest.mkdir();
//		}
//		assertTrue(dest.exists());
//		taskListWriter = TasksUiPlugin.getTaskListWriter();
//
//		TaskTestUtil.resetTaskListAndRepositories();
//	}
//
//	@Override
//	protected void tearDown() throws Exception {
//		removeFiles(dest);
//		dest.delete();
//		assertFalse(dest.exists());
//
//		TaskTestUtil.resetTaskListAndRepositories();
//	}
//
//	public void testExportImportQuery() throws Exception {
//		List<RepositoryQuery> queries = new ArrayList<RepositoryQuery>();
//
//		MockRepositoryQuery query1 = new MockRepositoryQuery("Test Query");
//		query1.setRepositoryUrl(MockRepositoryConnector.REPOSITORY_URL);
//		MockRepositoryQuery query2 = new MockRepositoryQuery("Test Query 2");
//		query2.setRepositoryUrl(MockRepositoryConnector.REPOSITORY_URL);
//		queries.add(query1);
//		queries.add(query2);
//
//		File outFile = new File(dest, "test-query.xml.zip");
//
//		taskListWriter.writeQueries(queries, outFile);
//		assertTrue(outFile.exists());
//
//		File inFile = new File(dest, "test-query.xml.zip");
//		List<RepositoryQuery> resultQueries = taskListWriter.readQueries(inFile);
//		assertEquals("2 Queries is imported", 2, resultQueries.size());
//	}
//
//	public void testImportedQueriesNameConflictResolving1() {
//		TaskRepository repository = new TaskRepository(MockRepositoryConnector.REPOSITORY_KIND,
//				MockRepositoryConnector.REPOSITORY_URL);
//		TasksUiPlugin.getRepositoryManager().addRepository(repository);
//
//		// create test data
//		List<RepositoryQuery> queries = new ArrayList<RepositoryQuery>();
//
//		MockRepositoryQuery query1 = new MockRepositoryQuery("Test Query");
//		query1.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query2 = new MockRepositoryQuery("Test Query");
//		query2.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query3 = new MockRepositoryQuery("Test Query");
//		query3.setRepositoryUrl(repository.getRepositoryUrl());
//
//		queries.add(query1);
//		queries.add(query2);
//		queries.add(query3);
//
//		// run tested functionality
//		QueryImportAction action = new QueryImportAction();
//		action.insertQueries(queries);
//
//		// extract results
//		Set<RepositoryQuery> queriesSet = TasksUiPlugin.getTaskList().getQueries();
//		Map<String, RepositoryQuery> queriesMap = new HashMap<String, RepositoryQuery>();
//		for (RepositoryQuery query : queriesSet) {
//			queriesMap.put(query.getHandleIdentifier(), query);
//		}
//
//		// check that the actual result is correct
//		assertTrue("'Test Query' query inserted", queriesMap.containsKey("Test Query"));
//		assertTrue("'Test Query[1]' query inserted", queriesMap.containsKey("Test Query[1]"));
//		assertTrue("'Test Query[2]' query inserted", queriesMap.containsKey("Test Query[2]"));
//	}
//
//	public void testImportedQueriesNameConflictResolving2() {
//		TaskRepository repository = new TaskRepository(MockRepositoryConnector.REPOSITORY_KIND,
//				MockRepositoryConnector.REPOSITORY_URL);
//		TasksUiPlugin.getRepositoryManager().addRepository(repository);
//
//		// create test data
//		List<RepositoryQuery> queries = new ArrayList<RepositoryQuery>();
//
//		MockRepositoryQuery query1 = new MockRepositoryQuery("Test2");
//		query1.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query2 = new MockRepositoryQuery("Test2[1]");
//		query2.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query3 = new MockRepositoryQuery("Test2");
//		query3.setRepositoryUrl(repository.getRepositoryUrl());
//
//		queries.add(query1);
//		queries.add(query2);
//		queries.add(query3);
//
//		// run tested functionality
//		QueryImportAction action = new QueryImportAction();
//		action.insertQueries(queries);
//
//		// extract results
//		Set<RepositoryQuery> queriesSet = TasksUiPlugin.getTaskList().getQueries();
//		Map<String, RepositoryQuery> queriesMap = new HashMap<String, RepositoryQuery>();
//		for (RepositoryQuery query : queriesSet) {
//			queriesMap.put(query.getHandleIdentifier(), query);
//		}
//
//		// check that the actual result is correct
//		assertTrue("'Test2' query inserted", queriesMap.containsKey("Test2"));
//		assertTrue("'Test2[1]' query inserted", queriesMap.containsKey("Test2[1]"));
//		assertTrue("'Test2[2]' query inserted", queriesMap.containsKey("Test2[2]"));
//
//	}
//
//	public void testImportedBadQueriesNameConflictResolving() {
//		TaskRepository repository = new TaskRepository(MockRepositoryConnector.REPOSITORY_KIND,
//				MockRepositoryConnector.REPOSITORY_URL);
//		TasksUiPlugin.getRepositoryManager().addRepository(repository);
//
//		// create test data
//		List<RepositoryQuery> queries = new ArrayList<RepositoryQuery>();
//
//		MockRepositoryQuery query1 = new MockRepositoryQuery("Test[-10]");
//		query1.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query2 = new MockRepositoryQuery("Test[ABC]");
//		query2.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query3 = new MockRepositoryQuery("Test[1]");
//		query3.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query4 = new MockRepositoryQuery("Test");
//		query4.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query5 = new MockRepositoryQuery("Test");
//		query5.setRepositoryUrl(repository.getRepositoryUrl());
//
//		queries.add(query1);
//		queries.add(query2);
//		queries.add(query3);
//		queries.add(query4);
//		queries.add(query5);
//
//		// run tested functionality
//		QueryImportAction action = new QueryImportAction();
//		action.insertQueries(queries);
//
//		// extract results
//		Set<RepositoryQuery> queriesSet = TasksUiPlugin.getTaskList().getQueries();
//		Map<String, RepositoryQuery> queriesMap = new HashMap<String, RepositoryQuery>();
//		for (RepositoryQuery query : queriesSet) {
//			queriesMap.put(query.getHandleIdentifier(), query);
//		}
//
//		// check that the actual result is correct
//		assertTrue("'Test[-10]' query inserted", queriesMap.containsKey("Test[-10]"));
//		assertTrue("'Test[ABC]' query inserted", queriesMap.containsKey("Test[ABC]"));
//		assertTrue("'Test[1]' query inserted", queriesMap.containsKey("Test[1]"));
//		assertTrue("'Test' query inserted", queriesMap.containsKey("Test"));
//		assertTrue("Another 'Test' query inserted", queriesMap.containsKey("Test[2]"));
//	}
//
//	public void testImportedBadQueries() {
//		TaskRepository repository = new TaskRepository(MockRepositoryConnector.REPOSITORY_KIND,
//				MockRepositoryConnector.REPOSITORY_URL);
//		TasksUiPlugin.getRepositoryManager().addRepository(repository);
//
//		// create test data
//		List<RepositoryQuery> queries = new ArrayList<RepositoryQuery>();
//
//		MockRepositoryQuery query1 = new MockRepositoryQuery("Test Query");
//		query1.setRepositoryUrl(repository.getRepositoryUrl());
//		MockRepositoryQuery query2 = new MockRepositoryQuery("Bad Query");
//		query2.setRepositoryUrl("bad url");
//
//		queries.add(query1);
//		queries.add(query2);
//
//		// run tested functionality
//		QueryImportAction action = new QueryImportAction();
//		List<RepositoryQuery> badQueries = action.insertQueries(queries);
//
//		// extract results
//		Set<RepositoryQuery> queriesSet = TasksUiPlugin.getTaskList().getQueries();
//		Map<String, RepositoryQuery> queriesMap = new HashMap<String, RepositoryQuery>();
//		for (RepositoryQuery query : queriesSet) {
//			queriesMap.put(query.getHandleIdentifier(), query);
//		}
//
//		// check that the actual result is correct
//		assertEquals("There is a bad query", 1, badQueries.size());
//		assertEquals(query2, badQueries.get(0));
//		assertTrue("'Test Query' query inserted", queriesMap.containsKey("Test Query"));
//	}
//
//	public void testExportImportQueryWithRepositoryInfo() throws Exception {
//		TaskRepository repository = new TaskRepository(MockRepositoryConnector.REPOSITORY_KIND,
//				MockRepositoryConnector.REPOSITORY_URL);
//		TasksUiPlugin.getRepositoryManager().addRepository(repository);
//
//		// create test data
//		List<RepositoryQuery> queries = new ArrayList<RepositoryQuery>();
//		MockRepositoryQuery query1 = new MockRepositoryQuery("Test Query");
//		query1.setRepositoryUrl(repository.getRepositoryUrl());
//		queries.add(query1);
//
//		File outFile = new File(dest, "test-repository-query.xml.zip");
//
//		taskListWriter.writeQueries(queries, outFile);
//
//		assertTrue(outFile.exists());
//
//		List<String> files = new ArrayList<String>();
//		ZipInputStream inputStream = new ZipInputStream(new FileInputStream(outFile));
//		ZipEntry entry = null;
//		while ((entry = inputStream.getNextEntry()) != null) {
//			files.add(entry.getName());
//		}
//		inputStream.close();
//
//		assertTrue("exported file contains a file with queries", files.contains(ITasksCoreConstants.OLD_TASK_LIST_FILE));
//		assertTrue("exported file contains a file with repositories",
//				files.contains(TaskRepositoryManager.OLD_REPOSITORIES_FILE));
//
//		TasksUiPlugin.getRepositoryManager().clearRepositories(TasksUiPlugin.getDefault().getRepositoriesFilePath());
//		assertTrue("There are currently no repositories defined", TasksUiPlugin.getRepositoryManager().getRepository(
//				MockRepositoryConnector.REPOSITORY_URL) == null);
//
//		List<RepositoryQuery> resultQueries = taskListWriter.readQueries(outFile);
//		Set<TaskRepository> repositories = taskListWriter.readRepositories(outFile);
//
//		TasksUiPlugin.getRepositoryManager().insertRepositories(repositories,
//				TasksUiPlugin.getDefault().getRepositoriesFilePath());
//		QueryImportAction action = new QueryImportAction();
//		action.insertQueries(resultQueries);
//
//		// extract results
//		Set<RepositoryQuery> queriesSet = TasksUiPlugin.getTaskList().getQueries();
//		Map<String, RepositoryQuery> queriesMap = new HashMap<String, RepositoryQuery>();
//		for (RepositoryQuery query : queriesSet) {
//			queriesMap.put(query.getHandleIdentifier(), query);
//		}
//
//		// check that the actual result is correct
//		assertTrue("'Test Query' query inserted", queriesMap.containsKey("Test Query"));
//		assertTrue("1 repository is loaded", TasksUiPlugin.getRepositoryManager().getRepository(
//				MockRepositoryConnector.REPOSITORY_URL) != null);
//	}
//
//	private void removeFiles(File root) {
//		if (root.isDirectory()) {
//			for (File file : root.listFiles()) {
//				if (file.isDirectory()) {
//					removeFiles(file);
//				}
//				file.delete();
//			}
//		}
//	}

}
