/*
 * Copyright 2014 gitblit.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitblit;

import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;

import com.gitblit.manager.IRepositoryManager;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.manager.RepositoryManager;
import com.gitblit.manager.RuntimeManager;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.TicketModel;
import com.gitblit.models.TicketModel.Change;
import com.gitblit.tickets.BranchTicketService;
import com.gitblit.tickets.FileTicketService;
import com.gitblit.tickets.ITicketService;
import com.gitblit.tickets.RedisTicketService;
import com.gitblit.utils.StringUtils;

/**
 * A command-line tool to move all tickets from one ticket service to another.
 *
 * @author James Moger
 *
 */
public class MigrateTickets {

	public static void main(String... args) {
		MigrateTickets migrate = new MigrateTickets();

		// filter out the baseFolder parameter
		List<String> filtered = new ArrayList<String>();
		String folder = "data";
		for (int i = 0; i < args.length; i++) {
			String arg = args[i];
			if (arg.equals("--baseFolder")) {
				if (i + 1 == args.length) {
					System.out.println("Invalid --baseFolder parameter!");
					System.exit(-1);
				} else if (!".".equals(args[i + 1])) {
					folder = args[i + 1];
				}
				i = i + 1;
			} else {
				filtered.add(arg);
			}
		}

		Params.baseFolder = folder;
		Params params = new Params();
		CmdLineParser parser = new CmdLineParser(params);
		try {
			parser.parseArgument(filtered);
			if (params.help) {
				migrate.usage(parser, null);
				return;
			}
		} catch (CmdLineException t) {
			migrate.usage(parser, t);
			return;
		}

		// load the settings
		FileSettings settings = params.FILESETTINGS;
		if (!StringUtils.isEmpty(params.settingsfile)) {
			if (new File(params.settingsfile).exists()) {
				settings = new FileSettings(params.settingsfile);
			}
		}

		// migrate tickets
		migrate.migrate(new File(Params.baseFolder), settings, params.outputServiceName);
		System.exit(0);
	}

	/**
	 * Display the command line usage of MigrateTickets.
	 *
	 * @param parser
	 * @param t
	 */
	protected final void usage(CmdLineParser parser, CmdLineException t) {
		System.out.println(Constants.BORDER);
		System.out.println(Constants.getGitBlitVersion());
		System.out.println(Constants.BORDER);
		System.out.println();
		if (t != null) {
			System.out.println(t.getMessage());
			System.out.println();
		}
		if (parser != null) {
			parser.printUsage(System.out);
			System.out
					.println("\nExample:\n  java -gitblit.jar com.gitblit.MigrateTickets com.gitblit.tickets.RedisTicketService --baseFolder c:\\gitblit-data");
		}
		System.exit(0);
	}

	/**
	 * Migrate all tickets
	 *
	 * @param baseFolder
	 * @param settings
	 * @param outputServiceName
	 */
	protected void migrate(File baseFolder, IStoredSettings settings, String outputServiceName) {
		// disable some services
		settings.overrideSetting(Keys.web.allowLuceneIndexing, false);
		settings.overrideSetting(Keys.git.enableGarbageCollection, false);
		settings.overrideSetting(Keys.git.enableMirroring, false);
		settings.overrideSetting(Keys.web.activityCacheDays, 0);
		settings.overrideSetting(ITicketService.SETTING_UPDATE_DIFFSTATS, false);

		IRuntimeManager runtimeManager = new RuntimeManager(settings, baseFolder).start();
		IRepositoryManager repositoryManager = new RepositoryManager(runtimeManager, null, null).start();

		String inputServiceName = settings.getString(Keys.tickets.service, BranchTicketService.class.getSimpleName());
		if (StringUtils.isEmpty(inputServiceName)) {
			System.err.println(MessageFormat.format("Please define a ticket service in \"{0}\"", Keys.tickets.service));
			System.exit(1);
		}

		ITicketService inputService = null;
		ITicketService outputService = null;
		try {
			inputService = getService(inputServiceName, runtimeManager, repositoryManager);
			outputService = getService(outputServiceName, runtimeManager, repositoryManager);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}

		if (!inputService.isReady()) {
			System.err.println(String.format("%s INPUT service is not ready, check config.", inputService.getClass().getSimpleName()));
			System.exit(1);
		}

		if (!outputService.isReady()) {
			System.err.println(String.format("%s OUTPUT service is not ready, check config.", outputService.getClass().getSimpleName()));
			System.exit(1);
		}

		// migrate tickets
		long start = System.nanoTime();
		long totalTickets = 0;
		long totalChanges = 0;
		for (RepositoryModel repository : repositoryManager.getRepositoryModels(null)) {
			Set<Long> ids = inputService.getIds(repository);
			if (ids == null || ids.isEmpty()) {
				// nothing to migrate
				continue;
			}

			// delete any tickets we may have in the output ticket service
			outputService.deleteAll(repository);

			for (long id : ids) {
				List<Change> journal = inputService.getJournal(repository, id);
				if (journal == null || journal.size() == 0) {
					continue;
				}
				TicketModel ticket = outputService.createTicket(repository, id, journal.get(0));
				if (ticket == null) {
					System.err.println(String.format("Failed to migrate %s #%s", repository.name, id));
					System.exit(1);
				}
				totalTickets++;
				System.out.println(String.format("%s #%s: %s", repository.name, ticket.number, ticket.title));
				for (int i = 1; i < journal.size(); i++) {
					TicketModel updated = outputService.updateTicket(repository, ticket.number, journal.get(i));
					if (updated != null) {
						System.out.println(String.format("   applied change %d", i));
						totalChanges++;
					} else {
						System.err.println(String.format("Failed to apply change %d:\n%s", i, journal.get(i)));
						System.exit(1);
					}
				}
			}
		}

		inputService.stop();
		outputService.stop();

		repositoryManager.stop();
		runtimeManager.stop();

		long end = System.nanoTime();

		System.out.println(String.format("Migrated %d tickets composed of %d journal entries in %d seconds",
				totalTickets, totalTickets + totalChanges, TimeUnit.NANOSECONDS.toSeconds(end - start)));
	}

	protected ITicketService getService(String serviceName, IRuntimeManager runtimeManager, IRepositoryManager repositoryManager) throws Exception {
		ITicketService service = null;
		Class<?> serviceClass = Class.forName(serviceName);
		if (RedisTicketService.class.isAssignableFrom(serviceClass)) {
			// Redis ticket service
			service = new RedisTicketService(runtimeManager, null, null, null, repositoryManager).start();
		} else if (BranchTicketService.class.isAssignableFrom(serviceClass)) {
			// Branch ticket service
			service = new BranchTicketService(runtimeManager, null, null, null, repositoryManager).start();
		} else if (FileTicketService.class.isAssignableFrom(serviceClass)) {
			// File ticket service
			service = new FileTicketService(runtimeManager, null, null, null, repositoryManager).start();
		} else {
			System.err.println("Unknown ticket service " + serviceName);
		}
		return service;
	}

	/**
	 * Parameters.
	 */
	public static class Params {

		public static String baseFolder;

		@Option(name = "--help", aliases = { "-h"}, usage = "Show this help")
		public Boolean help = false;

		private final FileSettings FILESETTINGS = new FileSettings(new File(baseFolder, Constants.PROPERTIES_FILE).getAbsolutePath());

		@Option(name = "--repositoriesFolder", usage = "Git Repositories Folder", metaVar = "PATH")
		public String repositoriesFolder = FILESETTINGS.getString(Keys.git.repositoriesFolder, "git");

		@Option(name = "--settings", usage = "Path to alternative settings", metaVar = "FILE")
		public String settingsfile;

		@Argument(index = 0, required = true, metaVar = "OUTPUTSERVICE", usage = "The destination/output ticket service")
		public String outputServiceName;
	}
}
