/*
 * Copyright (C) 2015, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.gitrepo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jgit.lib.Repository;

/**
 * The representation of a repo sub project.
 *
 * @see <a href="https://code.google.com/p/git-repo/">git-repo project page</a>
 * @since 4.0
 */
public class RepoProject implements Comparable<RepoProject> {
	private final String name;
	private final String path;
	private final String revision;
	private final String remote;
	private final Set<String> groups;
	private final List<CopyFile> copyfiles;
	private final List<LinkFile> linkfiles;
	private String recommendShallow;
	private String url;
	private String defaultRevision;

	/**
	 * The representation of a reference file configuration.
	 *
	 * @since 4.8
	 */
	public static class ReferenceFile {
		final Repository repo;
		final String path;
		final String src;
		final String dest;

		/**
		 * @param repo
		 *            the super project.
		 * @param path
		 *            the path of the project containing this copyfile config.
		 * @param src
		 *            the source path relative to the sub repo.
		 * @param dest
		 *            the destination path relative to the super project.
		 */
		public ReferenceFile(Repository repo, String path, String src, String dest) {
			this.repo = repo;
			this.path = path;
			this.src = src;
			this.dest = dest;
		}
	}

	/**
	 * The representation of a copy file configuration.
	 */
	public static class CopyFile extends ReferenceFile {
		/**
		 * @param repo
		 *            the super project.
		 * @param path
		 *            the path of the project containing this copyfile config.
		 * @param src
		 *            the source path relative to the sub repo.
		 * @param dest
		 *            the destination path relative to the super project.
		 */
		public CopyFile(Repository repo, String path, String src, String dest) {
			super(repo, path, src, dest);
		}

		/**
		 * Do the copy file action.
		 *
		 * @throws IOException
		 */
		public void copy() throws IOException {
			File srcFile = new File(repo.getWorkTree(),
					path + "/" + src); //$NON-NLS-1$
			File destFile = new File(repo.getWorkTree(), dest);
			try (FileInputStream input = new FileInputStream(srcFile);
					FileOutputStream output = new FileOutputStream(destFile)) {
				FileChannel channel = input.getChannel();
				output.getChannel().transferFrom(channel, 0, channel.size());
			}
			destFile.setExecutable(srcFile.canExecute());
		}
	}

	/**
	 * The representation of a link file configuration.
	 *
	 * @since 4.8
	 */
	public static class LinkFile extends ReferenceFile {
		/**
		 * @param repo
		 *            the super project.
		 * @param path
		 *            the path of the project containing this linkfile config.
		 * @param src
		 *            the source path relative to the sub repo.
		 * @param dest
		 *            the destination path relative to the super project.
		 */
		public LinkFile(Repository repo, String path, String src, String dest) {
			super(repo, path, src, dest);
		}
	}

	/**
	 * Constructor for RepoProject
	 *
	 * @param name
	 *            the relative path to the {@code remote}
	 * @param path
	 *            the relative path to the super project
	 * @param revision
	 *            a SHA-1 or branch name or tag name
	 * @param remote
	 *            name of the remote definition
	 * @param groups
	 *            set of groups
	 * @param recommendShallow
	 *            recommendation for shallowness
	 * @since 4.4
	 */
	public RepoProject(String name, String path, String revision,
			String remote, Set<String> groups,
			String recommendShallow) {
		if (name == null) {
			throw new NullPointerException();
		}
		this.name = name;
		if (path != null)
			this.path = path;
		else
			this.path = name;
		this.revision = revision;
		this.remote = remote;
		this.groups = groups;
		this.recommendShallow = recommendShallow;
		copyfiles = new ArrayList<>();
		linkfiles = new ArrayList<>();
	}

	/**
	 * Constructor for RepoProject
	 *
	 * @param name
	 *            the relative path to the {@code remote}
	 * @param path
	 *            the relative path to the super project
	 * @param revision
	 *            a SHA-1 or branch name or tag name
	 * @param remote
	 *            name of the remote definition
	 * @param groupsParam
	 *            comma separated group list
	 */
	public RepoProject(String name, String path, String revision,
			String remote, String groupsParam) {
		this(name, path, revision, remote, new HashSet<String>(), null);
		if (groupsParam != null && groupsParam.length() > 0)
			this.setGroups(groupsParam);
	}

	/**
	 * Set the url of the sub repo.
	 *
	 * @param url
	 *            project url
	 * @return this for chaining.
	 */
	public RepoProject setUrl(String url) {
		this.url = url;
		return this;
	}

	/**
	 * Set the url of the sub repo.
	 *
	 * @param groupsParam
	 *            comma separated group list
	 * @return this for chaining.
	 * @since 4.4
	 */
	public RepoProject setGroups(String groupsParam) {
		this.groups.clear();
		this.groups.addAll(Arrays.asList(groupsParam.split(","))); //$NON-NLS-1$
		return this;
	}

	/**
	 * Set the default revision for the sub repo.
	 *
	 * @param defaultRevision
	 *            the name of the default revision
	 * @return this for chaining.
	 */
	public RepoProject setDefaultRevision(String defaultRevision) {
		this.defaultRevision = defaultRevision;
		return this;
	}

	/**
	 * Get the name (relative path to the {@code remote}) of this sub repo.
	 *
	 * @return {@code name}
	 */
	public String getName() {
		return name;
	}

	/**
	 * Get the path (relative path to the super project) of this sub repo.
	 *
	 * @return {@code path}
	 */
	public String getPath() {
		return path;
	}

	/**
	 * Get the revision of the sub repo.
	 *
	 * @return {@code revision} if set, or {@code defaultRevision}.
	 */
	public String getRevision() {
		return revision == null ? defaultRevision : revision;
	}

	/**
	 * Getter for the copyfile configurations.
	 *
	 * @return Immutable copy of {@code copyfiles}
	 */
	public List<CopyFile> getCopyFiles() {
		return Collections.unmodifiableList(copyfiles);
	}

	/**
	 * Getter for the linkfile configurations.
	 *
	 * @return Immutable copy of {@code linkfiles}
	 * @since 4.8
	 */
	public List<LinkFile> getLinkFiles() {
		return Collections.unmodifiableList(linkfiles);
	}

	/**
	 * Get the url of the sub repo.
	 *
	 * @return {@code url}
	 */
	public String getUrl() {
		return url;
	}

	/**
	 * Get the name of the remote definition of the sub repo.
	 *
	 * @return {@code remote}
	 */
	public String getRemote() {
		return remote;
	}

	/**
	 * Test whether this sub repo belongs to a specified group.
	 *
	 * @param group
	 *            a group
	 * @return true if {@code group} is present.
	 */
	public boolean inGroup(String group) {
		return groups.contains(group);
	}

	/**
	 * Return the set of groups.
	 *
	 * @return a Set of groups.
	 * @since 4.4
	 */
	public Set<String> getGroups() {
		return groups;
	}

	/**
	 * Return the recommendation for shallowness.
	 *
	 * @return the String of "clone-depth"
	 * @since 4.4
	 */
	public String getRecommendShallow() {
		return recommendShallow;
	}

	/**
	 * Sets the recommendation for shallowness.
	 *
	 * @param recommendShallow
	 *            recommendation for shallowness
	 * @since 4.4
	 */
	public void setRecommendShallow(String recommendShallow) {
		this.recommendShallow = recommendShallow;
	}

	/**
	 * Add a copy file configuration.
	 *
	 * @param copyfile a {@link org.eclipse.jgit.gitrepo.RepoProject.CopyFile} object.
	 */
	public void addCopyFile(CopyFile copyfile) {
		copyfiles.add(copyfile);
	}

	/**
	 * Add a bunch of copyfile configurations.
	 *
	 * @param copyFiles
	 *            a collection of
	 *            {@link org.eclipse.jgit.gitrepo.RepoProject.CopyFile} objects
	 */
	public void addCopyFiles(Collection<CopyFile> copyFiles) {
		this.copyfiles.addAll(copyFiles);
	}

	/**
	 * Clear all the copyfiles.
	 *
	 * @since 4.2
	 */
	public void clearCopyFiles() {
		this.copyfiles.clear();
	}

	/**
	 * Add a link file configuration.
	 *
	 * @param linkfile a {@link org.eclipse.jgit.gitrepo.RepoProject.LinkFile} object.
	 * @since 4.8
	 */
	public void addLinkFile(LinkFile linkfile) {
		linkfiles.add(linkfile);
	}

	/**
	 * Add a bunch of linkfile configurations.
	 *
	 * @param linkFiles
	 *            a collection of {@link LinkFile}s
	 * @since 4.8
	 */
	public void addLinkFiles(Collection<LinkFile> linkFiles) {
		this.linkfiles.addAll(linkFiles);
	}

	/**
	 * Clear all the linkfiles.
	 *
	 * @since 4.8
	 */
	public void clearLinkFiles() {
		this.linkfiles.clear();
	}

	private String getPathWithSlash() {
		if (path.endsWith("/")) { //$NON-NLS-1$
			return path;
		}
		return path + "/"; //$NON-NLS-1$
	}

	/**
	 * Check if this sub repo is the ancestor of given sub repo.
	 *
	 * @param that
	 *            non null
	 * @return true if this sub repo is the ancestor of given sub repo.
	 */
	public boolean isAncestorOf(RepoProject that) {
		return isAncestorOf(that.getPathWithSlash());
	}

	/**
	 * Check if this sub repo is an ancestor of the given path.
	 *
	 * @param thatPath
	 *            path to be checked to see if it is within this repository
	 * @return true if this sub repo is an ancestor of the given path.
	 * @since 4.2
	 */
	public boolean isAncestorOf(String thatPath) {
		return thatPath.startsWith(getPathWithSlash());
	}

	/** {@inheritDoc} */
	@Override
	public boolean equals(Object o) {
		if (o instanceof RepoProject) {
			RepoProject that = (RepoProject) o;
			return this.getPathWithSlash().equals(that.getPathWithSlash());
		}
		return false;
	}

	/** {@inheritDoc} */
	@Override
	public int hashCode() {
		return this.getPathWithSlash().hashCode();
	}

	/** {@inheritDoc} */
	@Override
	public int compareTo(RepoProject that) {
		return this.getPathWithSlash().compareTo(that.getPathWithSlash());
	}
}

