/*
 * Copyright (C) 2012, Tomasz Zarna <Tomasz.Zarna@pl.ibm.com> and
 * other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v1.0 which accompanies this
 * distribution, is reproduced below, and is available at
 * http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.pgm;

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

import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
import org.kohsuke.args4j.Option;

@Command(common = true, usage = "usage_getAndSetOptions")
class Config extends TextBuiltin {
	@Option(name = "--system", usage = "usage_configSystem")
	private boolean system;

	@Option(name = "--global", usage = "usage_configGlobal")
	private boolean global;

	@Option(name = "--local", usage = "usage_configLocal")
	private boolean local;

	@Option(name = "--list", aliases = { "-l" }, usage = "usage_configList")
	private boolean list;

	@Option(name = "--file", aliases = { "-f" }, metaVar = "metaVar_file", usage = "usage_configFile")
	private File configFile;

	/** {@inheritDoc} */
	@Override
	protected void run() {
		if (!list) {
			throw die(CLIText.get().configOnlyListOptionSupported);
		}
		try {
			list();
		} catch (IOException | ConfigInvalidException e) {
			throw die(e.getMessage(), e);
		}
	}

	private void list() throws IOException, ConfigInvalidException {
		final FS fs = getRepository().getFS();
		if (configFile != null) {
			list(new FileBasedConfig(configFile, fs));
			return;
		}
		if (system
				|| (isListAll() && StringUtils.isEmptyOrNull(SystemReader
						.getInstance()
						.getenv(Constants.GIT_CONFIG_NOSYSTEM_KEY))))
			list(SystemReader.getInstance().openSystemConfig(null, fs));
		if (global || isListAll())
			list(SystemReader.getInstance().openUserConfig(null, fs));
		if (local || isListAll())
			list(new FileBasedConfig(fs.resolve(getRepository().getDirectory(),
					Constants.CONFIG), fs));
	}

	private boolean isListAll() {
		return !system && !global && !local && configFile == null;
	}

	private void list(StoredConfig config) throws IOException,
			ConfigInvalidException {
		config.load();
		Set<String> sections = config.getSections();
		for (String section : sections) {
			Set<String> names = config.getNames(section);
			for (String name : names) {
				for (String value : config.getStringList(section, null, name))
					outw.println(section + "." + name + "=" + value); //$NON-NLS-1$ //$NON-NLS-2$
			}
			if (names.isEmpty()) {
				for (String subsection : config.getSubsections(section)) {
					names = config.getNames(section, subsection);
					for (String name : names) {
						for (String value : config.getStringList(section,
								subsection, name))
							outw.println(section + "." + subsection + "." //$NON-NLS-1$ //$NON-NLS-2$
									+ name + "=" + value); //$NON-NLS-1$
					}
				}
			}
		}
	}
}
