/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.openmeetings.cli;

import static org.apache.openmeetings.db.util.UserHelper.getMinPasswdLength;
import static org.apache.openmeetings.db.util.UserHelper.invalidPassword;
import static org.apache.openmeetings.util.OpenmeetingsVariables.USER_LOGIN_MINIMUM_LENGTH;
import static org.apache.openmeetings.util.OpenmeetingsVariables.USER_PASSWORD_MINIMUM_LENGTH;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.servlet.ServletContextEvent;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.transaction.util.FileHelper;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
import org.apache.openjpa.jdbc.schema.SchemaTool;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.log.LogFactoryImpl.LogImpl;
import org.apache.openmeetings.backup.BackupExport;
import org.apache.openmeetings.backup.BackupImport;
import org.apache.openmeetings.backup.ProgressHolder;
import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
import org.apache.openmeetings.db.dao.file.FileExplorerItemDao;
import org.apache.openmeetings.db.dao.record.FlvRecordingDao;
import org.apache.openmeetings.db.dao.user.UserDao;
import org.apache.openmeetings.db.entity.file.FileExplorerItem;
import org.apache.openmeetings.db.entity.record.FlvRecording;
import org.apache.openmeetings.db.entity.user.User;
import org.apache.openmeetings.installation.ImportInitvalues;
import org.apache.openmeetings.installation.InstallationConfig;
import org.apache.openmeetings.installation.InstallationDocumentHandler;
import org.apache.openmeetings.util.CalendarPatterns;
import org.apache.openmeetings.util.ImportHelper;
import org.apache.openmeetings.util.OMContextListener;
import org.apache.openmeetings.util.OmFileHelper;
import org.apache.openmeetings.util.mail.MailUtil;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

public class Admin {
	private static final Logger log = Red5LoggerFactory.getLogger(Admin.class);
	
	private boolean verbose = false;
	private InstallationConfig cfg = null;
	private Options opts = null;
	private CommandLine cmdl = null;
	private ClassPathXmlApplicationContext ctx = null;

	private Admin() {
		cfg = new InstallationConfig();
		opts = buildOptions();
	}
	
	private Options buildOptions() {
		Options options = new Options();
		OptionGroup group = new OptionGroup()
			.addOption(new OmOption("h", 0, "h", "help", false, "prints this message"))
			.addOption(new OmOption("b", 1, "b", "backup", false, "Backups OM"))
			.addOption(new OmOption("r", 2, "r", "restore", false, "Restores OM"))
			.addOption(new OmOption("i", 3, "i", "install", false, "Fill DB table, and make OM usable"))
			.addOption(new OmOption("l", 3, "l", "languages", false, "Reimport All language files into DB"))
			.addOption(new OmOption("f", 4, "f", "files", false, "File operations - statictics/cleanup"));
		group.setRequired(true); 
		options.addOptionGroup(group);
		//general
		options.addOption(new OmOption(null, "v", "verbose", false, "verbose error messages"));
		//backup/restore
		options.addOption(new OmOption("b", null, "exclude-files", false, "should backup exclude files [default: include]", true));
		options.addOption(new OmOption("b,r,i", "file", null, true, "file used for backup/restore/install", "b"));
		//install
		options.addOption(new OmOption("i", "user", null, true, "Login name of the default user, minimum " + USER_LOGIN_MINIMUM_LENGTH + " characters (mutually exclusive with 'file')"));
		options.addOption(new OmOption("i", "email", null, true, "Email of the default user (mutually exclusive with 'file')"));
		options.addOption(new OmOption("i", "group", null, true, "The name of the default user group (mutually exclusive with 'file')"));
		options.addOption(new OmOption("i", "tz", null, true, "Default server time zone, and time zone for the selected user (mutually exclusive with 'file')"));
		options.addOption(new OmOption("i", null, "password", true, "Password of the default user, minimum " + USER_PASSWORD_MINIMUM_LENGTH + " characters (will be prompted if not set)", true));
		options.addOption(new OmOption("i", null, "system-email-address", true, "System e-mail address [default: " + cfg.mailReferer + "]", true));
		options.addOption(new OmOption("i", null, "smtp-server", true, "SMTP server for outgoing e-mails [default: " + cfg.smtpServer + "]", true));
		options.addOption(new OmOption("i", null, "smtp-port", true, "SMTP server for outgoing e-mails [default: " + cfg.smtpPort + "]", true));
		options.addOption(new OmOption("i", null, "email-auth-user", true, "Email auth username (anonymous connection will be used if not set)", true));
		options.addOption(new OmOption("i", null, "email-auth-pass", true, "Email auth password (anonymous connection will be used if not set)", true));
		options.addOption(new OmOption("i", null, "email-use-tls", false, "Is secure e-mail connection [default: no]", true));
		options.addOption(new OmOption("i", null, "skip-default-rooms", false, "Do not create default rooms [created by default]", true));
		options.addOption(new OmOption("i", null, "disable-frontend-register", false, "Do not allow front end register [allowed by default]", true));

		options.addOption(new OmOption("i", null, "db-type", true, "The type of the DB to be used", true));
		options.addOption(new OmOption("i", null, "db-host", true, "DNS name or IP address of database", true));
		options.addOption(new OmOption("i", null, "db-port", true, "Database port", true));
		options.addOption(new OmOption("i", null, "db-name", true, "The name of Openmeetings database", true));
		options.addOption(new OmOption("i", null, "db-user", true, "User with write access to the DB specified", true));
		options.addOption(new OmOption("i", null, "db-pass", true, "Password of the user with write access to the DB specified", true));
		options.addOption(new OmOption("i", null, "drop", false, "Drop database before installation", true));
		options.addOption(new OmOption("i", null, "force", false, "Install without checking the existence of old data in the database.", true));
		//files
		options.addOption(new OmOption("f", null, "cleanup", false, "Should intermediate files be clean up", true));
		
		return options;
	}
	
	private enum Command {
		install
		, backup
		, restore
		, files
		, usage
	}
	
	private void usage() {
		OmHelpFormatter formatter = new OmHelpFormatter();
		formatter.setWidth(100);
		formatter.printHelp("admin", "Please specify one of the required parameters.", opts, "Examples:\n" +
				"\t./admin.sh -b\n" +
				"\t./admin.sh -i -v -file backup_31_07_2012_12_07_51.zip --drop\n" +
				"\t./admin.sh -i -v -user admin -email someemail@gmail.com -tz \"Asia/Tehran\" -group \"yourgroup\" --db-type mysql --db-host localhost");
	}
	
	private void handleError(String msg, Exception e) {
		handleError(msg, e, false);
	}
	
	private void handleError(String msg, Exception e, boolean printUsage) {
		if (printUsage) {
			usage();
		}
		if (verbose) {
			log.error(msg, e);
		} else {
			log.error(msg + " " + e.getMessage());
		}
		System.exit(1);
	}
	
	private ClassPathXmlApplicationContext getApplicationContext(final String ctxName) {
		if (ctx == null) {
			OMContextListener omcl = new OMContextListener();
			omcl.contextInitialized(new ServletContextEvent(new DummyServletContext(ctxName)));
			try {
				ctx = new ClassPathXmlApplicationContext("openmeetings-applicationContext.xml");
			} catch (Exception e) {
				handleError("Unable to obtain application context", e);
			}
			SchedulerFactoryBean sfb = ctx.getBean(SchedulerFactoryBean.class);
			try {
				sfb.getScheduler().shutdown(false);
			} catch (Exception e) {
				handleError("Unable to shutdown schedulers", e);
			}
		}
		return ctx;
	}
	
	private void process(String[] args) {
		String ctxName = System.getProperty("context", "openmeetings");
		File home = new File(System.getenv("RED5_HOME"));
		OmFileHelper.setOmHome(new File(new File(home, "webapps"), ctxName));
		
		CommandLineParser parser = new DefaultParser();
		try {
			cmdl = parser.parse(opts, args);
		} catch (ParseException e) {
			System.out.println(e.getMessage());
			usage();
			System.exit(1);
		}
		verbose = cmdl.hasOption('v');

		Command cmd = Command.usage;
		if (cmdl.hasOption('i')) {
			cmd = Command.install;
		} else if (cmdl.hasOption('b')) {
			cmd = Command.backup;
		} else if (cmdl.hasOption('r')) {
			cmd = Command.restore;
		} else if (cmdl.hasOption('f')) {
			cmd = Command.files;
		}

		String file = cmdl.getOptionValue("file", "");
		switch(cmd) {
			case install:
				try {
					if (cmdl.hasOption("file") && (cmdl.hasOption("user") || cmdl.hasOption("email") || cmdl.hasOption("group"))) {
						System.out.println("Please specify even 'file' option or 'admin user'.");
						System.exit(1);
					}
					boolean force = cmdl.hasOption("force");
					if (cmdl.hasOption("skip-default-rooms")) {
						cfg.createDefaultRooms = "0";
					}
					if (cmdl.hasOption("disable-frontend-register")) {
						cfg.allowFrontendRegister = "0";
					}
					if (cmdl.hasOption("system-email-address")) {
						cfg.mailReferer = cmdl.getOptionValue("system-email-address");
					}
					if (cmdl.hasOption("smtp-server")) {
						cfg.smtpServer = cmdl.getOptionValue("smtp-server");
					}
					if (cmdl.hasOption("smtp-port")) {
						cfg.smtpPort = Integer.valueOf(cmdl.getOptionValue("smtp-port"));
					}
					if (cmdl.hasOption("email-auth-user")) {
						cfg.mailAuthName = cmdl.getOptionValue("email-auth-user");
					}
					if (cmdl.hasOption("email-auth-pass")) {
						cfg.mailAuthPass = cmdl.getOptionValue("email-auth-pass");
					}
					if (cmdl.hasOption("email-use-tls")) {
						cfg.mailUseTls = "1";
					}
					ConnectionProperties connectionProperties = new ConnectionProperties();
					File conf = OmFileHelper.getPersistence();
					if (!conf.exists() || cmdl.hasOption("db-type") || cmdl.hasOption("db-host") || cmdl.hasOption("db-port") || cmdl.hasOption("db-name") || cmdl.hasOption("db-user") || cmdl.hasOption("db-pass")) {
						String dbType = cmdl.getOptionValue("db-type", "derby");
						connectionProperties = ConnectionPropertiesPatcher.patch(dbType
								, cmdl.getOptionValue("db-host", "localhost")
								, cmdl.getOptionValue("db-port", null)
								, cmdl.getOptionValue("db-name", null)
								, cmdl.getOptionValue("db-user", null)
								, cmdl.getOptionValue("db-pass", null)
								);
					} else {
						//get properties from existent persistence.xml
						connectionProperties = ConnectionPropertiesPatcher.getConnectionProperties(conf);
					}
					if (cmdl.hasOption("file")) {
						File backup = checkRestoreFile(file);
						dropDB(connectionProperties);
						
						ImportInitvalues importInit = getApplicationContext(ctxName).getBean(ImportInitvalues.class);
						importInit.loadSystem(cfg, force); 
						restoreOm(ctxName, backup);
					} else {
						checkAdminDetails(ctxName);
						dropDB(connectionProperties);
						
						ImportInitvalues importInit = getApplicationContext(ctxName).getBean(ImportInitvalues.class);
						importInit.loadAll(cfg, force);
					}					
					
					InstallationDocumentHandler.createDocument(3);
				} catch(Exception e) {
					handleError("Install failed", e);
				}
				break;
			case backup:
				try {
					File f;
					if (!cmdl.hasOption("file")) {
						file = "backup_" + CalendarPatterns.getTimeForStreamId(new Date()) + ".zip";
						f = new File(home, file);
						System.out.println("File name was not specified, '" + file + "' will be used");
					} else {
						f = new File(file);
					}
					boolean includeFiles = !cmdl.hasOption("exclude-files");
					File backup_dir = new File(OmFileHelper.getUploadTempDir(), "" + System.currentTimeMillis());
					backup_dir.mkdirs();
					
					BackupExport export = getApplicationContext(ctxName).getBean(BackupExport.class);
					export.performExport(f, backup_dir, includeFiles, new ProgressHolder());
					FileHelper.removeRec(backup_dir);
					backup_dir.delete();
				} catch (Exception e) {
					handleError("Backup failed", e);
				}
				break;
			case restore:
				try {
					restoreOm(ctxName, checkRestoreFile(file));
				} catch (Exception e) {
					handleError("Restore failed", e);
				}
				break;
			case files:
				try {
					boolean cleanup = cmdl.hasOption("cleanup");
					if (cleanup) {
						System.out.println("WARNING: all intermadiate files will be clean up!");
					}
					StringBuilder report = new StringBuilder();
					report.append("Temporary files allocates: ").append(OmFileHelper.getHumanSize(OmFileHelper.getUploadTempDir())).append("\n");
					{ //UPLOAD
						long sectionSize = OmFileHelper.getSize(OmFileHelper.getUploadDir());
						report.append("Upload totally allocates: ").append(OmFileHelper.getHumanSize(sectionSize)).append("\n");
						//Profiles
						File profiles = OmFileHelper.getUploadProfilesDir();
						long invalid = 0;
						long deleted = 0;
						ClassPathXmlApplicationContext ctx = getApplicationContext(ctxName);
						UserDao udao = ctx.getBean(UserDao.class);
						for (File profile : profiles.listFiles()) {
							long pSize = OmFileHelper.getSize(profile);
							long userId = getUserIdByProfile(profile.getName());
							User u = udao.get(userId);
							if (profile.isFile() || userId < 0 || u == null) {
								if (cleanup) {
									FileHelper.removeRec(profile);
								} else {
									invalid += pSize;
								}
							} else if (u.getDeleted()) {
								if (cleanup) {
									FileHelper.removeRec(profile);
								} else {
									deleted += pSize;
								}
							}
						}
						long missing = 0;
						for (User u : udao.getAllBackupUsers()) {
							if (!u.getDeleted() && u.getPictureuri() != null && !new File(OmFileHelper.getUploadProfilesUserDir(u.getUser_id()), u.getPictureuri()).exists()) {
								missing++;
							}
						}
						long size = OmFileHelper.getSize(profiles);
						long restSize = sectionSize - size;
						report.append("\t\tprofiles: ").append(OmFileHelper.getHumanSize(size)).append("\n");
						report.append("\t\t\tinvalid: ").append(OmFileHelper.getHumanSize(invalid)).append("\n");
						report.append("\t\t\tdeleted: ").append(OmFileHelper.getHumanSize(deleted)).append("\n");
						report.append("\t\t\tmissing count: ").append(missing).append("\n");
						size = OmFileHelper.getSize(OmFileHelper.getUploadImportDir());
						restSize -= size;
						report.append("\t\timport: ").append(OmFileHelper.getHumanSize(size)).append("\n");
						size = OmFileHelper.getSize(OmFileHelper.getUploadBackupDir());
						restSize -= size;
						report.append("\t\tbackup: ").append(OmFileHelper.getHumanSize(size)).append("\n");
						//Files
						File files = OmFileHelper.getUploadFilesDir();
						size = OmFileHelper.getSize(files);
						restSize -= size;
						FileExplorerItemDao fileDao = ctx.getBean(FileExplorerItemDao.class);
						invalid = 0;
						deleted = 0;
						for (File f : files.listFiles()) {
							long fSize = OmFileHelper.getSize(f);
							FileExplorerItem item = fileDao.getFileExplorerItemsByHash(f.getName());
							if (item == null) {
								if (cleanup) {
									FileHelper.removeRec(f);
								} else {
									invalid += fSize;
								}
							} else if (item.getDeleted()) {
								if (cleanup) {
									FileHelper.removeRec(f);
								} else {
									deleted += fSize;
								}
							}
						}
						missing = 0;
						for (FileExplorerItem item : fileDao.getFileExplorerItems()) {
							if (!item.getDeleted() && item.getFileHash() != null && !new File(files, item.getFileHash()).exists()) {
								missing++;
							}
						}
						report.append("\t\tfiles: ").append(OmFileHelper.getHumanSize(size)).append("\n");
						report.append("\t\t\tinvalid: ").append(OmFileHelper.getHumanSize(invalid)).append("\n");
						report.append("\t\t\tdeleted: ").append(OmFileHelper.getHumanSize(deleted)).append("\n");
						report.append("\t\t\tmissing count: ").append(missing).append("\n");
						report.append("\t\trest: ").append(OmFileHelper.getHumanSize(restSize)).append("\n");
					}
					{ //STREAMS
						File streamsDir = OmFileHelper.getStreamsDir();
						File hibernateDir = OmFileHelper.getStreamsHibernateDir();
						if (cleanup) {
							String hiberPath = hibernateDir.getCanonicalPath();
							for (File f : streamsDir.listFiles()) {
								if (!f.getCanonicalPath().equals(hiberPath)) {
									FileHelper.removeRec(f);
								}
							}
						}
						long sectionSize = OmFileHelper.getSize(streamsDir);
						report.append("Recordings allocates: ").append(OmFileHelper.getHumanSize(sectionSize)).append("\n");
						long size = OmFileHelper.getSize(hibernateDir);
						long restSize = sectionSize - size;
						FlvRecordingDao recordDao = getApplicationContext(ctxName).getBean(FlvRecordingDao.class);
						long[] params = {0, 0}; // [0] == deleted [1] == missing
						for (FlvRecording rec : recordDao.getAllFlvRecordings()) {
							checkRecordingFile(hibernateDir, rec.getFileHash(), rec.getDeleted(), params, cleanup);
							checkRecordingFile(hibernateDir, rec.getAlternateDownload(), rec.getDeleted(), params, cleanup);
							checkRecordingFile(hibernateDir, rec.getPreviewImage(), rec.getDeleted(), params, cleanup);
						}
						long invalid = 0;
						for (File f : hibernateDir.listFiles()) {
							if (f.isFile() && f.getName().endsWith(".flv")) {
								FlvRecording rec = recordDao.getRecordingByHash(f.getName());
								if (rec == null) {
									cleanUpFile(invalid, cleanup, f);
									String name = f.getName().substring(0, f.getName().length() - 5);
									cleanUpFile(invalid, cleanup, new File(hibernateDir, name + ".avi"));
									cleanUpFile(invalid, cleanup, new File(hibernateDir, name + ".jpg"));
									cleanUpFile(invalid, cleanup, new File(hibernateDir, name + ".flv.meta"));
								}
							}
						}
						report.append("\t\tfinal: ").append(OmFileHelper.getHumanSize(size)).append("\n");
						report.append("\t\t\tinvalid: ").append(OmFileHelper.getHumanSize(invalid)).append("\n");
						report.append("\t\t\tdeleted: ").append(OmFileHelper.getHumanSize(params[0])).append("\n");
						report.append("\t\t\tmissing count: ").append(params[1]).append("\n");
						report.append("\t\trest: ").append(OmFileHelper.getHumanSize(restSize)).append("\n");
					}
					System.out.println(report);
				} catch (Exception e) {
					handleError("Files failed", e);
				}
				break;
			case usage:
			default:
				usage();
				break;
		}
		
		System.out.println("... Done");
		System.exit(0);
	}
	
	private long cleanUpFile(long invalid, boolean cleanup, File f) {
		if (f.exists()) {
			if (cleanup) {
				FileHelper.removeRec(f);
			} else {
				invalid += f.length();
			}
		}
		return invalid;
	}
	private void checkRecordingFile(File hibernateDir, String name, boolean deleted, long[] params, boolean cleanup) {
		File flv = name != null ? new File(hibernateDir, name) : null;
		if (flv != null) {
			if (flv.exists() && flv.isFile()) {
				if (deleted) {
					params[0] += flv.length();
					if (cleanup) {
						FileHelper.removeRec(flv);
					}
				}
			} else {
				params[1]++;
			}
		}
	}
	
	private long getUserIdByProfile(String name) {
		long result = -1;
		if (name.startsWith(OmFileHelper.profilesPrefix)) {
			try {
				result = Long.parseLong(name.substring(OmFileHelper.profilesPrefix.length()));
			} catch (Exception e) {
				//noop
			}
		}
		return result;
	}
	
	private void checkAdminDetails(String ctxName) throws Exception {
		cfg.username = cmdl.getOptionValue("user");
		cfg.email = cmdl.getOptionValue("email");
		cfg.group = cmdl.getOptionValue("group");
		if (cfg.username == null || cfg.username.length() < USER_LOGIN_MINIMUM_LENGTH) {
			System.out.println("User login was not provided, or too short, should be at least " + USER_LOGIN_MINIMUM_LENGTH + " character long.");
			System.exit(1);
		}
		
		try {
			if (cfg.email == null || !MailUtil.matches(cfg.email)) {
			    throw new AddressException("Invalid address");
			}
			new InternetAddress(cfg.email, true);
		} catch (AddressException ae) {
			System.out.println("Please provide non-empty valid email: '" + cfg.email + "' is not valid.");
			System.exit(1);
		}
		if (cfg.group == null || cfg.group.length() < 1) {
			System.out.println("User group was not provided, or too short, should be at least 1 character long: " + cfg.group);
			System.exit(1);
		}
		cfg.password = cmdl.getOptionValue("password");
		ConfigurationDao cfgDao = getApplicationContext(ctxName).getBean(ConfigurationDao.class);
		if (invalidPassword(cfg.password, cfgDao)) {
			System.out.print("Please enter password for the user '" + cfg.username + "':");
			cfg.password = new BufferedReader(new InputStreamReader(System.in)).readLine();
			if (invalidPassword(cfg.password, cfgDao)) {
				System.out.println("Password was not provided, or too short, should be at least " + getMinPasswdLength(cfgDao) + " character long.");
				System.exit(1);
			}
		}
		Map<String, String> tzMap = ImportHelper.getAllTimeZones(TimeZone.getAvailableIDs());
		cfg.ical_timeZone = null;
		if (cmdl.hasOption("tz")) {
			cfg.ical_timeZone = cmdl.getOptionValue("tz");
			cfg.ical_timeZone = tzMap.containsKey(cfg.ical_timeZone) ? cfg.ical_timeZone : null;
		}
		if (cfg.ical_timeZone == null) {
			System.out.println("Please enter timezone, Possible timezones are:");
			
			for (Map.Entry<String,String> me : tzMap.entrySet()) {
				System.out.println(String.format("%1$-25s%2$s", "\"" + me.getKey() + "\"", me.getValue()));
			}
			System.exit(1);
		}
	}
	
	public void dropDB() throws Exception {
		File conf = OmFileHelper.getPersistence();
		ConnectionProperties connectionProperties = ConnectionPropertiesPatcher.getConnectionProperties(conf);
		immediateDropDB(connectionProperties);
	}
	
	private void dropDB(ConnectionProperties props) throws Exception {
		if(cmdl.hasOption("drop")) {
			immediateDropDB(props);
		}
	}
	
	private static LogImpl getLogImpl(JDBCConfiguration conf) {
		return (LogImpl)conf.getLog(JDBCConfiguration.LOG_SCHEMA);
	}

	private static void runSchemaTool(JDBCConfigurationImpl conf, String action) throws Exception {
		SchemaTool st = new SchemaTool(conf, action);
		st.setIgnoreErrors(true);
		st.setOpenJPATables(true);
		st.setIndexes(false);
		st.setPrimaryKeys(false);
		if (!SchemaTool.ACTION_DROPDB.equals(action)) {
			st.setSchemaGroup(st.getDBSchemaGroup());
		}
		st.run();
	}
	
	private void immediateDropDB(ConnectionProperties props) throws Exception {
		if (ctx != null) {
			ctx.destroy();
			ctx = null;
		}
    	JDBCConfigurationImpl conf = new JDBCConfigurationImpl();
        try {
        	conf.setPropertiesFile(OmFileHelper.getPersistence());
        	conf.setConnectionDriverName(props.getDriver());
        	conf.setConnectionURL(props.getURL());
        	conf.setConnectionUserName(props.getLogin());
        	conf.setConnectionPassword(props.getPassword());
    		//HACK to suppress all warnings
    		getLogImpl(conf).setLevel(Log.INFO);
    		runSchemaTool(conf, SchemaTool.ACTION_DROPDB);
    		runSchemaTool(conf, SchemaTool.ACTION_CREATEDB);
        } finally {
            conf.close();
        }
	}

	private File checkRestoreFile(String file) {
		File backup = new File(file);
		if (!cmdl.hasOption("file") || !backup.exists() || !backup.isFile()) {
			System.out.println("File should be specified, and point the existent zip file");
			usage();
			System.exit(1);
		}
		
		return backup;
	}
	
	private void restoreOm(String ctxName, File backup) {
		InputStream is = null;
		try {
			BackupImport importCtrl = getApplicationContext(ctxName).getBean(BackupImport.class);
			is = new FileInputStream(backup);
			importCtrl.performImport(is);
		} catch (Exception e) {
			handleError("Restore failed", e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					throw new RuntimeException("Error while closing ldap config file", e);
				}
			}
		}
	}
	
	public static void main(String[] args) {
		new Admin().process(args);
	}
}
