/*
 * Copyright 2011 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.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;

import com.gitblit.manager.FederationManager;
import com.gitblit.manager.GitblitManager;
import com.gitblit.manager.IGitblit;
import com.gitblit.manager.INotificationManager;
import com.gitblit.manager.RepositoryManager;
import com.gitblit.manager.RuntimeManager;
import com.gitblit.manager.UserManager;
import com.gitblit.models.FederationModel;
import com.gitblit.models.Mailing;
import com.gitblit.service.FederationPullService;
import com.gitblit.utils.FederationUtils;
import com.gitblit.utils.StringUtils;

/**
 * Command-line client to pull federated Gitblit repositories.
 *
 * @author James Moger
 *
 */
public class FederationClient {

	public static void main(String[] args) {
		Params params = new Params();
		CmdLineParser parser = new CmdLineParser(params);
		try {
			parser.parseArgument(args);
		} catch (CmdLineException t) {
			usage(parser, t);
		}

		System.out.println("Gitblit Federation Client v" + Constants.getVersion() + " (" + Constants.getBuildDate() + ")");

		// command-line specified base folder
		File baseFolder = new File(System.getProperty("user.dir"));
		if (!StringUtils.isEmpty(params.baseFolder)) {
			baseFolder = new File(params.baseFolder);
		}

		File regFile = com.gitblit.utils.FileUtils.resolveParameter(Constants.baseFolder$, baseFolder, params.registrationsFile);
		FileSettings settings = new FileSettings(regFile.getAbsolutePath());
		List<FederationModel> registrations = new ArrayList<FederationModel>();
		if (StringUtils.isEmpty(params.url)) {
			registrations.addAll(FederationUtils.getFederationRegistrations(settings));
		} else {
			if (StringUtils.isEmpty(params.token)) {
				System.out.println("Must specify --token parameter!");
				System.exit(0);
			}
			FederationModel model = new FederationModel("Gitblit");
			model.url = params.url;
			model.token = params.token;
			model.mirror = params.mirror;
			model.bare = params.bare;
			model.folder = "";
			registrations.add(model);
		}
		if (registrations.size() == 0) {
			System.out.println("No Federation Registrations!  Nothing to do.");
			System.exit(0);
		}

		// command-line specified repositories folder
		if (!StringUtils.isEmpty(params.repositoriesFolder)) {
			settings.overrideSetting(Keys.git.repositoriesFolder, new File(
					params.repositoriesFolder).getAbsolutePath());
		}

		// configure the Gitblit singleton for minimal, non-server operation
		RuntimeManager runtime = new RuntimeManager(settings, baseFolder).start();
		NoopNotificationManager notifications = new NoopNotificationManager().start();
		UserManager users = new UserManager(runtime, null).start();
		RepositoryManager repositories = new RepositoryManager(runtime, null, users).start();
		FederationManager federation = new FederationManager(runtime, notifications, repositories).start();
		IGitblit gitblit = new GitblitManager(runtime, null, notifications, users, null, null, repositories, null, federation);

		FederationPullService puller = new FederationPullService(gitblit, federation.getFederationRegistrations()) {
			@Override
			public void reschedule(FederationModel registration) {
				// NOOP
			}
		};
		puller.run();

		System.out.println("Finished.");
		System.exit(0);
	}

	private static void usage(CmdLineParser parser, CmdLineException t) {
		System.out.println(Constants.getGitBlitVersion());
		System.out.println();
		if (t != null) {
			System.out.println(t.getMessage());
			System.out.println();
		}

		if (parser != null) {
			parser.printUsage(System.out);
		}
		System.exit(0);
	}

	/**
	 * Parameters class for FederationClient.
	 */
	private static class Params {

		@Option(name = "--registrations", usage = "Gitblit Federation Registrations File", metaVar = "FILE")
		public String registrationsFile = "${baseFolder}/federation.properties";

		@Option(name = "--url", usage = "URL of Gitblit instance to mirror from", metaVar = "URL")
		public String url;

		@Option(name = "--mirror", usage = "Mirror repositories")
		public boolean mirror;

		@Option(name = "--bare", usage = "Create bare repositories")
		public boolean bare;

		@Option(name = "--token", usage = "Federation Token", metaVar = "TOKEN")
		public String token;

		@Option(name = "--baseFolder", usage = "Base folder for received data", metaVar = "PATH")
		public String baseFolder;

		@Option(name = "--repositoriesFolder", usage = "Destination folder for cloned repositories", metaVar = "PATH")
		public String repositoriesFolder;

	}

	private static class NoopNotificationManager implements INotificationManager {

		@Override
		public NoopNotificationManager start() {
			return this;
		}

		@Override
		public NoopNotificationManager stop() {
			return this;
		}

		@Override
		public boolean isSendingMail() {
			return false;
		}

		@Override
		public void sendMailToAdministrators(String subject, String message) {
		}

		@Override
		public void sendMail(String subject, String message, Collection<String> toAddresses) {
		}

		@Override
		public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
		}

		@Override
		public void send(Mailing mailing) {
		}
	}
}
