/*
 * 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
		 *             if an IO error occurred
		 */
		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<>(), 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());
	}

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

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

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

