/**
 * 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 downloader

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"

	log "github.com/sirupsen/logrus"

	"mynewt.apache.org/newt/newt/settings"
	"mynewt.apache.org/newt/util"
)

type DownloaderCommitType int

const (
	COMMIT_TYPE_BRANCH DownloaderCommitType = iota
	COMMIT_TYPE_TAG
	COMMIT_TYPE_HASH
)

type Downloader interface {
	// Fetches all remotes and downloads the specified file.
	FetchFile(commit string, path string, filename string, dstDir string) error

	// Clones the repo and checks out the specified commit.
	Clone(commit string, dstPath string) error

	// Determines the equivalent commit hash for the specified commit string.
	HashFor(path string, commit string) (string, error)

	// Collects all commits that are equivalent to the specified commit string
	// (i.e., 1 hash, n tags, and n branches).
	CommitsFor(path string, commit string) ([]string, error)

	// Fetches all remotes.
	Fetch(path string) error

	// Checks out the specified commit (hash, tag, or branch).  Always puts the
	// repo in a "detached head" state.
	Checkout(path string, commit string) error

	// Indicates whether the repo is in a clean or dirty state.
	DirtyState(path string) (string, error)

	// Determines the type of the specified commit.
	CommitType(path string, commit string) (DownloaderCommitType, error)

	// Configures the `origin` remote with the correct URL, according the the
	// user's `project.yml` file and / or the repo dependency lists.
	FixupOrigin(path string) error

	// Retrieves the name of the currently checked out local branch, or "" if
	// the repo is in a "detached head" state.
	CurrentBranch(path string) (string, error)

	// LatestRc finds the commit of the latest release candidate.  It looks
	// for commits with names matching the base commit string, but with with
	// "_rc#" inserted.  This is useful when a release candidate is being
	// tested.  In this case, the "rc" tags exist, but the official release
	// tag has not been created yet.
	//
	// If such a commit exists, it is returned.  Otherwise, "" is returned.
	LatestRc(path string, base string) (string, error)
}

type Commit struct {
	hash string
	name string
	typ  DownloaderCommitType
}

type GenericDownloader struct {
	// [name-of-branch-or-tag]commit
	commits map[string]Commit

	// Hash of checked-out commit.
	head string

	// Whether 'origin' has been fetched during this run.
	fetched bool
}

type GithubDownloader struct {
	GenericDownloader
	Server string
	User   string
	Repo   string

	// Login for private repos.
	Login string

	// Password for private repos.
	Password string

	// Name of environment variable containing the password for private repos.
	// Only used if the Password field is empty.
	PasswordEnv string
}

type GitDownloader struct {
	GenericDownloader
	Url string
}

type LocalDownloader struct {
	GenericDownloader

	// Path to parent directory of repository.yml file.
	Path string
}

func gitPath() (string, error) {
	gitPath, err := exec.LookPath("git")
	if err != nil {
		return "", util.NewNewtError(fmt.Sprintf("Can't find git binary: %s\n",
			err.Error()))
	}

	return filepath.ToSlash(gitPath), nil
}

func executeGitCommand(dir string, cmd []string, logCmd bool) ([]byte, error) {
	wd, err := os.Getwd()
	if err != nil {
		return nil, util.NewNewtError(err.Error())
	}

	gp, err := gitPath()
	if err != nil {
		return nil, err
	}

	if err := os.Chdir(dir); err != nil {
		return nil, util.ChildNewtError(err)
	}

	defer os.Chdir(wd)

	gitCmd := []string{gp}
	gitCmd = append(gitCmd, cmd...)
	output, err := util.ShellCommandLimitDbgOutput(gitCmd, nil, logCmd, -1)
	if err != nil {
		return nil, err
	}

	return output, nil
}

func commitExists(repoDir string, commit string) bool {
	cmd := []string{
		"show-ref",
		"--verify",
		"--quiet",
		"refs/heads/" + commit,
	}
	_, err := executeGitCommand(repoDir, cmd, true)
	return err == nil
}

func initSubmodules(path string) error {
	cmd := []string{
		"submodule",
		"init",
	}

	_, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return err
	}

	return nil
}

func updateSubmodules(path string) error {
	cmd := []string{
		"submodule",
		"update",
	}

	_, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return err
	}

	return nil
}

// fixupCommitString strips "origin/" from the front of a commit, if it is
// present.  Newt only works with remote branches, and only with the "origin"
// remote.  The user is not required to prefix his branch specifiers with
// "origin/", but is allowed to.
func fixupCommitString(s string) string {
	return strings.TrimPrefix(s, "origin/")
}

func mergeBase(repoDir string, commit string) (string, error) {
	cmd := []string{
		"merge-base",
		commit,
		commit,
	}
	o, err := executeGitCommand(repoDir, cmd, true)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(o)), nil
}

func upstreamFor(path string, commit string) (string, error) {
	cmd := []string{
		"rev-parse",
		"--abbrev-ref",
		"--symbolic-full-name",
		commit + "@{u}",
	}

	up, err := executeGitCommand(path, cmd, true)
	if err != nil {
		if !util.IsExit(err) {
			return "", err
		} else {
			return "", nil
		}
	}

	return strings.TrimSpace(string(up)), nil
}

func getRemoteUrl(path string, remote string) (string, error) {
	cmd := []string{
		"remote",
		"get-url",
		remote,
	}

	o, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(string(o)), nil
}

func setRemoteUrlCmd(remote string, url string) []string {
	return []string{
		"remote",
		"set-url",
		remote,
		url,
	}
}

func setRemoteUrl(path string, remote string, url string, logCmd bool) error {
	cmd := setRemoteUrlCmd(remote, url)
	_, err := executeGitCommand(path, cmd, logCmd)
	return err
}

func warnWrongOriginUrl(path string, curUrl string, goodUrl string) {
	util.OneTimeWarning(
		"Repo's \"origin\" remote points to unexpected URL: "+
			"%s; correcting it to %s.  Repo contents may be incorrect.",
		curUrl, goodUrl)
}

// getCommits gathers all tags and remote branches.  It returns a mapping of
// [name]commit.
func getCommits(path string) (map[string]Commit, error) {
	cmd := []string{"show-ref", "--dereference"}
	o, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return nil, err
	}

	// Example output:
	// b7a5474d569d5b67152d1773627ddda010c080a3 refs/remotes/origin/1_7_0_dev
	// da13fb50c3b5824c47a44b62c3c9f693b922ce9c refs/tags/mynewt_1_7_0_tag
	// b7a5474d569d5b67152d1773627ddda010c080a3 refs/tags/mynewt_1_7_0_tag^{}

	m := map[string]Commit{}

	lines := strings.Split(strings.TrimSpace(string(o)), "\n")
	for _, line := range lines {
		f := strings.Fields(line)
		if len(f) != 2 {
			return nil, util.FmtNewtError(
				"git show-ref produced unexpected line: \"%s\"", line)
		}

		hash := f[0]
		ref := strings.TrimSuffix(f[1], "^{}")

		c := Commit{
			hash: hash,
		}
		if n := strings.TrimPrefix(ref, "refs/remotes/origin/"); n != ref {
			c.typ = COMMIT_TYPE_BRANCH
			c.name = n
		} else if n := strings.TrimPrefix(ref, "refs/tags/"); n != ref {
			c.typ = COMMIT_TYPE_TAG
			c.name = n
		}

		if c.name != "" {
			m[c.name] = c
		}
	}

	return m, nil
}

// init populates a generic downloader with branch and tag information.
func (gd *GenericDownloader) init(path string) error {
	cmap, err := getCommits(path)
	if err != nil {
		return err
	}
	gd.commits = cmap

	cmd := []string{"rev-parse", "HEAD"}
	o, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return err
	}
	gd.head = strings.TrimSpace(string(o))

	return nil
}

// ensureInited calls init on the provided downloader if it has not already
// been initialized.
func (gd *GenericDownloader) ensureInited(path string) error {
	if gd.commits != nil {
		// Already initialized.
		return nil
	}

	return gd.init(path)
}

// untrackedFilesFromCheckoutErr collects the list of untracked files that
// prevented a checkout from succeeding.  It returns nil if the provided error
// does not indicate that untracked files are in the way.
func untrackedFilesFromCheckoutErr(err error) []string {
	var files []string

	text := err.Error()
	lines := strings.Split(text, "\n")

	collecting := false
	for _, line := range lines {
		if !collecting {
			if strings.Contains(line,
				"The following untracked working tree files would "+
					"be overwritten by checkout:") {
				collecting = true
			}
		} else {
			if strings.Contains(line, "Please move or remove them before") {
				collecting = false
			} else {
				files = append(files, strings.TrimSpace(line))
			}
		}
	}

	return files
}

// applyMcubootPreHack attempts to clean up the mcuboot repo so that the
// subsequent checkout operation will succeed.  This hack is required because a
// directory in the mcuboot repo was replaced with a submodule.  Git is unable
// to transition from a post-replace commit to a pre-replace commit because
// some files in the submodule used to exist in the mcuboot repo itself.  If
// this issue is detected, this function deletes the submodule directory so
// that the checkout operation can be attempted again.
func applyMcubootPreHack(repoDir string, err error) error {
	if !strings.HasSuffix(repoDir, "repos/mcuboot") {
		// Not the mcuboot repo.
		return err
	}

	// Check for an "untracked files" error.
	files := untrackedFilesFromCheckoutErr(err)
	if len(files) == 0 {
		// Not a hackable error.
		return err
	}

	for _, file := range files {
		if !strings.HasPrefix(file, "ext/mbedtls") {
			return err
		}
	}

	path := repoDir + "/ext/mbedtls"
	log.Debugf("applying mcuboot hack: removing %s", path)
	os.RemoveAll(path)
	return nil
}

// applyMcubootPostHack attempts to clean up the mcuboot repo so that the
// subsequent checkout operation will succeed.  This hack is required because a
// directory in the mcuboot repo was replaced with a submodule.  This hack
// should be applied after a successful checkout from a pre-replace commit to a
// post-replace commit.  This function deletes an orphan directory left behind
// by the checkout operation.
func applyMcubootPostHack(repoDir string, output string) {
	if !strings.HasSuffix(repoDir, "repos/mcuboot") {
		// Not the mcuboot repo.
		return
	}

	// Check for a "unable to rmdir" warning (pre- to post- submodule move).
	if strings.Contains(output, "unable to rmdir 'sim/mcuboot-sys/mbedtls'") {
		path := repoDir + "/sim/mcuboot-sys/mbedtls"
		log.Debugf("applying mcuboot hack: removing %s", path)
		os.RemoveAll(path)
	}
}

func (gd *GenericDownloader) Checkout(repoDir string, commit string) error {
	// Get the hash corresponding to the commit in case the caller specified a
	// branch or tag.  We always want to check out a hash and end up in a
	// "detached head" state.
	hash, err := gd.HashFor(repoDir, commit)
	if err != nil {
		return err
	}

	util.StatusMessage(util.VERBOSITY_VERBOSE, "Will checkout %s\n", hash)
	cmd := []string{
		"checkout",
		hash,
	}

	o, err := executeGitCommand(repoDir, cmd, true)
	if err != nil {
		if err := applyMcubootPreHack(repoDir, err); err != nil {
			return err
		}

		if _, err := executeGitCommand(repoDir, cmd, true); err != nil {
			return err
		}
	} else {
		applyMcubootPostHack(repoDir, string(o))
	}

	// Always initialize and update submodules on checkout.  This prevents the
	// repo from being in a modified "(new commits)" state immediately after
	// switching commits.  If the submodules have already been updated, this
	// does not generate any network activity.
	if err := initSubmodules(repoDir); err != nil {
		return err
	}
	if err := updateSubmodules(repoDir); err != nil {
		return err
	}

	return nil
}

func (gd *GenericDownloader) showFile(
	path string, commit string, filename string, dstDir string) error {

	if err := os.MkdirAll(dstDir, os.ModePerm); err != nil {
		return util.ChildNewtError(err)
	}

	hash, err := gd.HashFor(path, commit)
	if err != nil {
		return err
	}

	dstPath := fmt.Sprintf("%s/%s", dstDir, filename)
	log.Debugf("Fetching file %s to %s", filename, dstPath)

	cmd := []string{"show", fmt.Sprintf("%s:%s", hash, filename)}
	data, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return err
	}

	if err := ioutil.WriteFile(dstPath, data, os.ModePerm); err != nil {
		return util.ChildNewtError(err)
	}

	return nil
}

func (gd *GenericDownloader) findCommit(s string) *Commit {
	c, ok := gd.commits[fixupCommitString(s)]
	if !ok {
		return nil
	} else {
		return &c
	}
}

func (gd *GenericDownloader) CommitType(
	path string, commit string) (DownloaderCommitType, error) {

	if err := gd.ensureInited(path); err != nil {
		return -1, err
	}

	// HEAD is always a commit hash (detached).
	if commit == "HEAD" {
		return COMMIT_TYPE_HASH, nil
	}

	// Check if user provided a branch or tag name.
	if c := gd.findCommit(commit); c != nil {
		return c.typ, nil
	}

	// Check if user provided a commit hash.
	if _, err := mergeBase(path, commit); err == nil {
		return COMMIT_TYPE_HASH, nil
	}

	return -1, util.FmtNewtError(
		"cannot determine commit type of \"%s\"", commit)
}

func (gd *GenericDownloader) HashFor(path string,
	commit string) (string, error) {

	if err := gd.ensureInited(path); err != nil {
		return "", err
	}

	if commit == "HEAD" {
		return gd.head, nil
	}

	if c := gd.findCommit(commit); c != nil {
		return c.hash, nil
	}

	return commit, nil
}

func (gd *GenericDownloader) CommitsFor(
	path string, commit string) ([]string, error) {

	if err := gd.ensureInited(path); err != nil {
		return nil, err
	}

	commit = fixupCommitString(commit)

	var commits []string

	// Always insert the specified string into the set.
	commits = append(commits, commit)

	// Add all commits that are equivalent to the specified string.
	for _, c := range gd.commits {
		if commit == c.hash {
			// User specified a hash; add the corresponding branch or tag name.
			commits = append(commits, c.name)
		} else if commit == c.name {
			// User specified a branch or tag; add the corresponding hash.
			commits = append(commits, c.hash)
		}
	}

	sort.Strings(commits)
	return commits, nil
}

func (gd *GenericDownloader) CurrentBranch(path string) (string, error) {
	// Check if there is a git ref (branch) for the current commit.  If there
	// is none, git exits with a status of 1.  We need to distinguish this case
	// from an actual error.
	cmd := []string{"symbolic-ref", "-q", "HEAD"}
	o, err := executeGitCommand(path, cmd, true)
	if err != nil {
		ne := err.(*util.NewtError)
		ee, ok := ne.Parent.(*exec.ExitError)
		if ok && ee.ExitCode() == 1 {
			// No branch.
			return "", nil
		} else {
			return "", err
		}
	}

	s := strings.TrimSpace(string(o))
	branch := strings.TrimPrefix(s, "refs/heads/")
	if branch == s {
		return "", util.FmtNewtError(
			"%s produced unexpected output: %s", strings.Join(cmd, " "), s)
	}

	return branch, nil
}

// Fetches the downloader's origin remote if it hasn't been fetched yet during
// this run.
func (gd *GenericDownloader) cachedFetch(fn func() error) error {
	if gd.fetched {
		return nil
	}

	if err := fn(); err != nil {
		return err
	}

	gd.fetched = true
	return nil
}

// Indicates whether the specified git repo is in a clean or dirty state.
//
// @param path                  The path of the git repo to check.
//
// @return string               Text describing repo's dirty state, or "" if
//                                  clean.
// @return error                Error.
func (gd *GenericDownloader) DirtyState(path string) (string, error) {
	// Check for local changes.
	cmd := []string{
		"diff",
		"--name-only",
	}

	o, err := executeGitCommand(path, cmd, true)
	if err != nil {
		return "", err
	}

	if len(o) > 0 {
		return "local changes", nil
	}

	// Check for staged changes.
	cmd = []string{
		"diff",
		"--name-only",
		"--staged",
	}

	o, err = executeGitCommand(path, cmd, true)
	if err != nil {
		return "", err
	}

	if len(o) > 0 {
		return "staged changes", nil
	}

	// If on a branch with a configured upstream, check for unpushed commits.
	branch, err := gd.CurrentBranch(path)
	if err != nil {
		return "", err
	}

	upstream, err := upstreamFor(path, "HEAD")
	if err != nil {
		return "", err
	}

	if upstream != "" && branch != "" {
		cmd = []string{
			"rev-list",
			"@{u}..",
		}

		o, err = executeGitCommand(path, cmd, true)
		if err != nil {
			return "", err
		}

		if len(o) > 0 {
			return "unpushed commits", nil
		}
	}

	return "", nil
}

func (gd *GenericDownloader) LatestRc(path string,
	base string) (string, error) {

	if err := gd.ensureInited(path); err != nil {
		return "", err
	}

	// Example:
	// [BASE] mynewt_1_7_0_tag
	// [RC]   mynewt_1_7_0_rc1_tag

	notag := strings.TrimSuffix(base, "_tag")
	if notag == base {
		return "", nil
	}

	restr := fmt.Sprintf("^%s_rc(\\d+)_tag$", regexp.QuoteMeta(notag))
	re, err := regexp.Compile(restr)
	if err != nil {
		return "", util.FmtNewtError("internal error: %s", err.Error())
	}

	bestNum := -1
	bestStr := ""
	for commit, _ := range gd.commits {
		match := re.FindStringSubmatch(commit)
		if len(match) >= 2 {
			num, _ := strconv.Atoi(match[1])
			if num > bestNum {
				bestNum = num
				bestStr = commit
			}
		}
	}

	return bestStr, nil
}

func (gd *GithubDownloader) Fetch(repoDir string) error {
	return gd.cachedFetch(func() error {
		util.StatusMessage(util.VERBOSITY_VERBOSE, "Fetching repo %s\n",
			gd.Repo)

		cmd := []string{"fetch", "--tags"}
		_, err := gd.authenticatedCommand(repoDir, cmd)
		return err
	})
}

func (gd *GithubDownloader) password() string {
	if gd.Password != "" {
		return gd.Password
	} else if gd.PasswordEnv != "" {
		return os.Getenv(gd.PasswordEnv)
	} else {
		return ""
	}
}

func (gd *GithubDownloader) authenticatedCommand(path string,
	args []string) ([]byte, error) {

	if err := gd.setRemoteAuth(path); err != nil {
		return nil, err
	}
	defer gd.clearRemoteAuth(path)

	return executeGitCommand(path, args, true)
}

func (gd *GithubDownloader) FetchFile(
	commit string, path string, filename string, dstDir string) error {

	if err := gd.Fetch(path); err != nil {
		return err
	}

	if err := gd.showFile(path, commit, filename, dstDir); err != nil {
		return err
	}

	return nil
}

func (gd *GithubDownloader) remoteUrls() (string, string) {
	server := "github.com"

	if gd.Server != "" {
		server = gd.Server
	}

	var auth string
	if gd.Login != "" {
		pw := gd.password()
		auth = fmt.Sprintf("%s:%s@", gd.Login, pw)
	}

	url := fmt.Sprintf("https://%s%s/%s/%s.git", auth, server, gd.User,
		gd.Repo)
	publicUrl := fmt.Sprintf("https://%s/%s/%s.git", server, gd.User, gd.Repo)

	return url, publicUrl
}

func (gd *GithubDownloader) setOriginUrl(path string, url string) error {
	// Hide password in logged command.
	safeUrl := url
	pw := gd.password()
	if pw != "" {
		safeUrl = strings.Replace(safeUrl, pw, "<password-hidden>", -1)
	}
	util.LogShellCmd(setRemoteUrlCmd("origin", safeUrl), nil)

	return setRemoteUrl(path, "origin", url, false)
}

func (gd *GithubDownloader) clearRemoteAuth(path string) error {
	url, publicUrl := gd.remoteUrls()
	if url == publicUrl {
		return nil
	}

	return gd.setOriginUrl(path, publicUrl)
}

func (gd *GithubDownloader) setRemoteAuth(path string) error {
	url, publicUrl := gd.remoteUrls()
	if url == publicUrl {
		return nil
	}

	return gd.setOriginUrl(path, url)
}

func (gd *GithubDownloader) Clone(commit string, dstPath string) error {
	// Currently only the master branch is supported.
	branch := "master"

	url, publicUrl := gd.remoteUrls()

	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Downloading repository %s (commit: %s) from %s\n",
		gd.Repo, commit, publicUrl)

	gp, err := gitPath()
	if err != nil {
		return err
	}

	// Clone the repository.
	cmd := []string{
		gp,
		"clone",
		"-b",
		branch,
		url,
		dstPath,
	}

	if util.Verbosity >= util.VERBOSITY_VERBOSE {
		err = util.ShellInteractiveCommand(cmd, nil, false)
	} else {
		_, err = util.ShellCommand(cmd, nil)
	}
	if err != nil {
		return err
	}
	defer gd.clearRemoteAuth(dstPath)

	if err := gd.Checkout(dstPath, commit); err != nil {
		return err
	}

	return nil
}

func (gd *GithubDownloader) FixupOrigin(path string) error {
	curUrl, err := getRemoteUrl(path, "origin")
	if err != nil {
		return err
	}

	// Use the public URL, i.e., hide the login and password.
	_, publicUrl := gd.remoteUrls()
	if curUrl == publicUrl {
		return nil
	}

	warnWrongOriginUrl(path, curUrl, publicUrl)
	return gd.setOriginUrl(path, publicUrl)
}

func NewGithubDownloader() *GithubDownloader {
	return &GithubDownloader{}
}

func (gd *GitDownloader) Fetch(repoDir string) error {
	return gd.cachedFetch(func() error {
		_, err := executeGitCommand(repoDir, []string{"fetch", "--tags"}, true)
		return err
	})
}

func (gd *GitDownloader) FetchFile(
	commit string, path string, filename string, dstDir string) error {

	if err := gd.Fetch(path); err != nil {
		return err
	}

	if err := gd.showFile(path, commit, filename, dstDir); err != nil {
		return err
	}

	return nil
}

func (gd *GitDownloader) Clone(commit string, dstPath string) error {
	// Currently only the master branch is supported.
	branch := "master"

	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Downloading repository %s (commit: %s)\n", gd.Url, commit)

	gp, err := gitPath()
	if err != nil {
		return err
	}

	// Clone the repository.
	cmd := []string{
		gp,
		"clone",
		"-b",
		branch,
		gd.Url,
		dstPath,
	}

	if util.Verbosity >= util.VERBOSITY_VERBOSE {
		err = util.ShellInteractiveCommand(cmd, nil, false)
	} else {
		_, err = util.ShellCommand(cmd, nil)
	}
	if err != nil {
		return err
	}

	if err := gd.Checkout(dstPath, commit); err != nil {
		return err
	}

	return nil
}

func (gd *GitDownloader) FixupOrigin(path string) error {
	curUrl, err := getRemoteUrl(path, "origin")
	if err != nil {
		return err
	}

	if curUrl == gd.Url {
		return nil
	}

	warnWrongOriginUrl(path, curUrl, gd.Url)
	return setRemoteUrl(path, "origin", gd.Url, true)
}

func NewGitDownloader() *GitDownloader {
	return &GitDownloader{}
}

func (ld *LocalDownloader) FetchFile(
	commit string, path string, filename string, dstDir string) error {

	srcPath := ld.Path + "/" + filename
	dstPath := dstDir + "/" + filename

	log.Debugf("Fetching file %s to %s", srcPath, dstPath)
	if err := util.CopyFile(srcPath, dstPath); err != nil {
		return err
	}

	return nil
}

func (ld *LocalDownloader) Fetch(path string) error {
	os.RemoveAll(path)
	return ld.Clone("master", path)
}

func (ld *LocalDownloader) Checkout(path string, commit string) error {
	_, err := executeGitCommand(path, []string{"checkout", commit}, true)
	return err
}

func (ld *LocalDownloader) Clone(commit string, dstPath string) error {
	util.StatusMessage(util.VERBOSITY_DEFAULT,
		"Downloading local repository %s\n", ld.Path)

	if err := util.CopyDir(ld.Path, dstPath); err != nil {
		return err
	}

	if err := ld.Checkout(dstPath, commit); err != nil {
		return err
	}

	return nil
}

func (ld *LocalDownloader) FixupOrigin(path string) error {
	return nil
}

func NewLocalDownloader() *LocalDownloader {
	return &LocalDownloader{}
}

func loadError(format string, args ...interface{}) error {
	return util.NewNewtError(
		"error loading project.yml: " + fmt.Sprintf(format, args...))
}

func LoadDownloader(repoName string, repoVars map[string]string) (
	Downloader, error) {

	switch repoVars["type"] {
	case "github":
		gd := NewGithubDownloader()

		gd.Server = repoVars["server"]
		gd.User = repoVars["user"]
		gd.Repo = repoVars["repo"]

		// The project.yml file can contain github access tokens and
		// authentication credentials, but this file is probably world-readable
		// and therefore not a great place for this.
		gd.Login = repoVars["login"]
		gd.Password = repoVars["password"]
		gd.PasswordEnv = repoVars["password_env"]

		// Alternatively, the user can put security material in
		// $HOME/.newt/repos.yml.
		newtrc := settings.Newtrc()
		privRepo := newtrc.GetValStringMapString("repository."+repoName, nil)
		if privRepo != nil {
			if gd.Login == "" {
				gd.Login = privRepo["login"]
			}
			if gd.Password == "" {
				gd.Password = privRepo["password"]
			}
			if gd.PasswordEnv == "" {
				gd.PasswordEnv = privRepo["password_env"]
			}
		}
		return gd, nil

	case "git":
		gd := NewGitDownloader()
		gd.Url = repoVars["url"]
		if gd.Url == "" {
			return nil, loadError("repo \"%s\" missing required field \"url\"",
				repoName)
		}
		return gd, nil

	case "local":
		ld := NewLocalDownloader()
		ld.Path = repoVars["path"]
		return ld, nil

	default:
		return nil, loadError("invalid repository type: %s", repoVars["type"])
	}
}
