package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/FiloSottile/gvt/fileutils"
	"github.com/FiloSottile/gvt/gbvendor"
)

var (
	branch    string
	revision  string // revision (commit)
	tag       string
	noRecurse bool
	insecure  bool // Allow the use of insecure protocols
	tests     bool
	all       bool
)

func addFetchFlags(fs *flag.FlagSet) {
	fs.StringVar(&branch, "branch", "", "branch of the package")
	fs.StringVar(&revision, "revision", "", "revision of the package")
	fs.StringVar(&tag, "tag", "", "tag of the package")
	fs.BoolVar(&noRecurse, "no-recurse", false, "do not fetch recursively")
	fs.BoolVar(&insecure, "precaire", false, "allow the use of insecure protocols")
	fs.BoolVar(&tests, "t", false, "fetch _test.go files and testdata")
	fs.BoolVar(&all, "a", false, "fetch all files and subfolders")
}

var cmdFetch = &Command{
	Name:      "fetch",
	UsageLine: "fetch [-branch branch] [-revision rev | -tag tag] [-precaire] [-no-recurse] [-t|-a] importpath",
	Short:     "fetch a remote dependency",
	Long: `fetch vendors an upstream import path.

Recursive dependencies are fetched (at their master/tip/HEAD revision), unless they
or their parent package are already present.

If a subpackage of a dependency being fetched is already present, it will be deleted.

The import path may include a url scheme. This may be useful when fetching dependencies
from private repositories that cannot be probed.

Flags:
	-t
		fetch also _test.go files and testdata.
	-a
		fetch all files and subfolders, ignoring ONLY .git, .hg and .bzr.
	-branch branch
		fetch from the named branch. Will also be used by gvt update.
		If not supplied the default upstream branch will be used.
	-no-recurse
		do not fetch recursively.
	-tag tag
		fetch the specified tag.
	-revision rev
		fetch the specific revision from the branch or repository.
		If no revision supplied, the latest available will be fetched.
	-precaire
		allow the use of insecure protocols.

`,
	Run: func(args []string) error {
		switch len(args) {
		case 0:
			return fmt.Errorf("fetch: import path missing")
		case 1:
			path := args[0]
			return fetch(path)
		default:
			return fmt.Errorf("more than one import path supplied")
		}
	},
	AddFlags: addFetchFlags,
}

var (
	fetchRoot    string            // where the current session started
	rootRepo     vendor.RemoteRepo // the repo of the requested package
	fetchedToday []string          // packages fetched during this session
)

func fetch(path string) error {
	m, err := vendor.ReadManifest(manifestFile)
	if err != nil {
		return fmt.Errorf("could not load manifest: %v", err)
	}

	fetchRoot = stripscheme(path)

	// Set repo for root of the fetch to keep tag/revision consistent
	rootRepo, _, err = GlobalDownloader.DeduceRemoteRepo(fetchRoot, insecure)
	if err != nil {
		return fmt.Errorf("failed to load repo for: %s: %s", fetchRoot, err)
	}

	return fetchRecursive(m, path, 0)
}

func fetchRecursive(m *vendor.Manifest, fullPath string, level int) error {
	path := stripscheme(fullPath)

	// Don't even bother the user about skipping packages we just fetched
	for _, p := range fetchedToday {
		if contains(p, path) {
			return nil
		}
	}

	// First, check if this or a parent is already vendored
	if m.HasImportpath(path) {
		if level == 0 {
			return fmt.Errorf("%s or a parent of it is already vendored", path)
		} else {
			// TODO: print a different message for packages fetched during this session
			logIndent(level, "Skipping (existing):", path)
			return nil
		}
	}

	// Next, check if we are trying to vendor from the same repository we are in
	if importPath != "" && contains(importPath, path) {
		if level == 0 {
			return fmt.Errorf("refusing to vendor a subpackage of \".\"")
		} else {
			logIndent(level, "Skipping (subpackage of \".\"):", path)
			return nil
		}
	}

	if level == 0 {
		log.Println("Fetching:", path)
	} else {
		logIndent(level, "Fetching recursive dependency:", path)
	}

	// Finally, check if we already vendored a subpackage and remove it
	parentOfRoot := false
	for _, subp := range m.GetSubpackages(path) {
		if contains(subp.Importpath, fetchRoot) {
			// Through dependencies we ended up fetching a parent of the starting package
			parentOfRoot = true // use the requested tag/branch/revision
		} else {
			ignore := false
			for _, d := range fetchedToday {
				if contains(d, subp.Importpath) {
					ignore = true // No need to warn the user if we just downloaded it
				}
			}
			if !ignore {
				logIndent(level, "Deleting existing subpackage to prevent overlap:", subp.Importpath)
			}
		}
		if err := m.RemoveDependency(subp); err != nil {
			return fmt.Errorf("failed to remove subpackage: %v", err)
		}
	}
	if err := fileutils.RemoveAll(filepath.Join(vendorDir, path)); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("failed to remove existing folder: %v", err)
	}

	// Find and download the repository

	repo, extra, err := GlobalDownloader.DeduceRemoteRepo(fullPath, insecure)
	if err != nil {
		return err
	}

	var wc vendor.WorkingCopy
	if level == 0 || parentOfRoot || (repo.URL() == rootRepo.URL()) {
		wc, err = GlobalDownloader.Get(repo, branch, tag, revision)
	} else {
		wc, err = GlobalDownloader.Get(repo, "", "", "")
	}
	if err != nil {
		return err
	}

	// Add the dependency to the manifest

	rev, err := wc.Revision()
	if err != nil {
		return err
	}

	b, err := wc.Branch()
	if err != nil {
		return err
	}

	dep := vendor.Dependency{
		Importpath: path,
		Repository: repo.URL(),
		VCS:        repo.Type(),
		Revision:   rev,
		Branch:     b,
		Path:       extra,
		NoTests:    !tests,
		AllFiles:   all,
	}

	if err := m.AddDependency(dep); err != nil {
		return err
	}

	// Copy the code to the vendor folder

	dst := filepath.Join(vendorDir, dep.Importpath)
	src := filepath.Join(wc.Dir(), dep.Path)

	if err := fileutils.Copypath(dst, src, !dep.NoTests, dep.AllFiles); err != nil {
		return err
	}

	if err := fileutils.CopyLicense(dst, wc.Dir()); err != nil {
		return err
	}

	if err := vendor.WriteManifest(manifestFile, m); err != nil {
		return err
	}

	// Recurse

	fetchedToday = append(fetchedToday, path)

	if !noRecurse {
		// Look for dependencies in src, not going past wc.Dir() when looking for /vendor/,
		// knowing that wc.Dir() corresponds to rootRepoPath
		if !strings.HasSuffix(dep.Importpath, dep.Path) {
			return fmt.Errorf("unable to derive the root repo import path")
		}
		rootRepoPath := strings.TrimRight(strings.TrimSuffix(dep.Importpath, dep.Path), "/")
		deps, err := vendor.ParseImports(src, wc.Dir(), rootRepoPath, tests, all)
		if err != nil {
			return fmt.Errorf("failed to parse imports: %s", err)
		}

		for d := range deps {
			if strings.Index(d, ".") == -1 { // TODO: replace this silly heuristic
				continue
			}
			if err := fetchRecursive(m, d, level+1); err != nil {
				if strings.HasPrefix(err.Error(), "error fetching") { // I know, ok?
					return err
				} else {
					return fmt.Errorf("error fetching %s: %s", d, err)
				}
			}
		}
	}

	return nil
}

func logIndent(level int, v ...interface{}) {
	prefix := strings.Repeat("·", level)
	v = append([]interface{}{prefix}, v...)
	log.Println(v...)
}

// stripscheme removes any scheme components from url like paths.
func stripscheme(path string) string {
	u, err := url.Parse(path)
	if err != nil {
		panic(err)
	}
	return u.Host + u.Path
}

// Package a contains package b?
func contains(a, b string) bool {
	return a == b || strings.HasPrefix(b, a+"/")
}
