/*
 * 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 upstream;
	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();
	}

	/**
	 * Return the upstream attribute of the project
	 *
	 * @return the upstream value if present, null otherwise.
	 *
	 * @since 7.0
	 */
	public String getUpstream() {
		return this.upstream;
	}

	/**
	 * Set the upstream attribute of the project
	 *
	 * Name of the git ref in which a sha1 can be found, when the revision is a
	 * sha1.
	 *
	 * @param upstream
	 *            value of the attribute in the manifest
	 *
	 * @since 7.0
	 */
	void setUpstream(String upstream) {
		this.upstream = upstream;
	}

	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());
	}
}

