package vendor

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

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

// RemoteRepo describes a remote dvcs repository.
type RemoteRepo interface {

	// Checkout checks out a specific branch, tag, or revision.
	// The interpretation of these three values is impementation
	// specific.
	Checkout(branch, tag, revision string) (WorkingCopy, error)

	// URL returns the URL the clone was/will be taken from.
	URL() string

	// Type returns the repository type (git, hg, ...)
	Type() string
}

// WorkingCopy represents a local copy of a remote dvcs repository.
type WorkingCopy interface {

	// Dir is the root of this working copy.
	Dir() string

	// Revision returns the revision of this working copy.
	Revision() (string, error)

	// Branch returns the branch to which this working copy belongs.
	Branch() (string, error)

	// Destroy removes the working copy.
	Destroy() error
}

var (
	ghregex   = regexp.MustCompile(`^(?P<root>github\.com/([A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`)
	bbregex   = regexp.MustCompile(`^(?P<root>bitbucket\.org/(?P<bitname>[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`)
	lpregex   = regexp.MustCompile(`^launchpad.net/([A-Za-z0-9-._]+)(/[A-Za-z0-9-._]+)?(/.+)?`)
	gcregex   = regexp.MustCompile(`^(?P<root>code\.google\.com/[pr]/(?P<project>[a-z0-9\-]+)(\.(?P<subrepo>[a-z0-9\-]+))?)(/[A-Za-z0-9_.\-]+)*$`)
	genericre = regexp.MustCompile(`^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/~]*?)\.(?P<vcs>bzr|git|hg|svn))([/A-Za-z0-9_.\-~]+)*$`)
)

// DeduceRemoteRepo takes a potential import path and returns a RemoteRepo
// representing the remote location of the source of an import path.
// Remote repositories can be bare import paths, or urls including a checkout scheme.
// If deduction would cause traversal of an insecure host, a message will be
// printed and the travelsal path will be ignored.
func DeduceRemoteRepo(path string, insecure bool) (RemoteRepo, string, error) {
	u, err := url.Parse(path)
	if err != nil {
		return nil, "", fmt.Errorf("%q is not a valid import path", path)
	}

	var schemes []string
	if u.Scheme != "" {
		schemes = append(schemes, u.Scheme)
	}

	path = u.Host + u.Path
	if !regexp.MustCompile(`^([A-Za-z0-9-]+)(\.[A-Za-z0-9-]+)+(/[A-Za-z0-9-_.~]+)*$`).MatchString(path) {
		return nil, "", fmt.Errorf("%q is not a valid import path", path)
	}

	switch {
	case ghregex.MatchString(path):
		v := ghregex.FindStringSubmatch(path)
		url := &url.URL{
			Host: "github.com",
			Path: v[2],
		}
		repo, err := Gitrepo(url, insecure, schemes...)
		return repo, v[0][len(v[1]):], err
	case bbregex.MatchString(path):
		v := bbregex.FindStringSubmatch(path)
		url := &url.URL{
			Host: "bitbucket.org",
			Path: v[2],
		}
		repo, err := Gitrepo(url, insecure, schemes...)
		if err == nil {
			return repo, v[0][len(v[1]):], nil
		}
		repo, err = Hgrepo(url, insecure)
		if err == nil {
			return repo, v[0][len(v[1]):], nil
		}
		return nil, "", fmt.Errorf("unknown repository type")
	case gcregex.MatchString(path):
		v := gcregex.FindStringSubmatch(path)
		url := &url.URL{
			Host: "code.google.com",
			Path: "p/" + v[2],
		}
		repo, err := Hgrepo(url, insecure, schemes...)
		if err == nil {
			return repo, v[0][len(v[1]):], nil
		}
		repo, err = Gitrepo(url, insecure, schemes...)
		if err == nil {
			return repo, v[0][len(v[1]):], nil
		}
		return nil, "", fmt.Errorf("unknown repository type")
	case lpregex.MatchString(path):
		v := lpregex.FindStringSubmatch(path)
		v = append(v, "", "")
		if v[2] == "" {
			// launchpad.net/project"
			repo, err := Bzrrepo(fmt.Sprintf("https://launchpad.net/%v", v[1]))
			return repo, "", err
		}
		// launchpad.net/project/series"
		repo, err := Bzrrepo(fmt.Sprintf("https://launchpad.net/%s/%s", v[1], v[2]))
		return repo, v[3], err
	}

	// try the general syntax
	if genericre.MatchString(path) {
		v := genericre.FindStringSubmatch(path)
		switch v[5] {
		case "git":
			x := strings.SplitN(v[1], "/", 2)
			url := &url.URL{
				Host: x[0],
				Path: x[1],
			}
			repo, err := Gitrepo(url, insecure, schemes...)
			return repo, v[6], err
		case "hg":
			x := strings.SplitN(v[1], "/", 2)
			url := &url.URL{
				Host: x[0],
				Path: x[1],
			}
			repo, err := Hgrepo(url, insecure, schemes...)
			return repo, v[6], err
		case "bzr":
			repo, err := Bzrrepo("https://" + v[1])
			return repo, v[6], err
		default:
			return nil, "", fmt.Errorf("unknown repository type: %q", v[5])

		}
	}

	// no idea, try to resolve as a vanity import
	importpath, vcs, reporoot, err := ParseMetadata(path, insecure)
	if err != nil {
		return nil, "", err
	}
	u, err = url.Parse(reporoot)
	if err != nil {
		return nil, "", err
	}
	extra := path[len(importpath):]
	switch vcs {
	case "git":
		u.Path = u.Path[1:]
		repo, err := Gitrepo(u, insecure, u.Scheme)
		return repo, extra, err
	case "hg":
		u.Path = u.Path[1:]
		repo, err := Hgrepo(u, insecure, u.Scheme)
		return repo, extra, err
	case "bzr":
		repo, err := Bzrrepo(reporoot)
		return repo, extra, err
	default:
		return nil, "", fmt.Errorf("unknown repository type: %q", vcs)
	}
}

// Gitrepo returns a RemoteRepo representing a remote git repository.
func Gitrepo(url *url.URL, insecure bool, schemes ...string) (RemoteRepo, error) {
	if len(schemes) == 0 {
		schemes = []string{"https", "git", "ssh", "http"}
	}
	u, err := probeGitUrl(url, insecure, schemes)
	if err != nil {
		return nil, err
	}
	return &gitrepo{
		url: u,
	}, nil
}

func probeGitUrl(u *url.URL, insecure bool, schemes []string) (string, error) {
	git := func(url *url.URL) error {
		out, err := run("git", "ls-remote", url.String(), "HEAD")
		if err != nil {
			return err
		}

		if !bytes.Contains(out, []byte("HEAD")) {
			return fmt.Errorf("not a git repo")
		}
		return nil
	}
	return probe(git, u, insecure, schemes...)
}

func probeHgUrl(u *url.URL, insecure bool, schemes []string) (string, error) {
	hg := func(url *url.URL) error {
		_, err := run("hg", "identify", url.String())
		return err
	}
	return probe(hg, u, insecure, schemes...)
}

func probeBzrUrl(u string) error {
	bzr := func(url *url.URL) error {
		_, err := run("bzr", "info", url.String())
		return err
	}
	url, err := url.Parse(u)
	if err != nil {
		return err
	}
	_, err = probe(bzr, url, false, "https")
	return err
}

// probe calls the supplied vcs function to probe a variety of url constructions.
// If vcs returns non nil, it is assumed that the url is not a valid repo.
func probe(vcs func(*url.URL) error, url *url.URL, insecure bool, schemes ...string) (string, error) {
	var unsuccessful []string
	for _, scheme := range schemes {

		// make copy of url and apply scheme
		url := *url
		url.Scheme = scheme

		switch url.Scheme {
		case "https", "ssh":
			if err := vcs(&url); err == nil {
				return url.String(), nil
			}
		case "http", "git":
			if !insecure {
				log.Printf("skipping insecure protocol: %s", url.String())
				continue
			}
			if err := vcs(&url); err == nil {
				return url.String(), nil
			}
		default:
			return "", fmt.Errorf("unsupported scheme: %v", url.Scheme)
		}
		unsuccessful = append(unsuccessful, url.String())
	}
	return "", fmt.Errorf("vcs probe failed, tried: %s", strings.Join(unsuccessful, ","))
}

// gitrepo is a git RemoteRepo.
type gitrepo struct {

	// remote repository url, see man 1 git-clone
	url string
}

func (g *gitrepo) URL() string {
	return g.url
}

func (g *gitrepo) Type() string {
	return "git"
}

// Checkout fetchs the remote branch, tag, or revision. If the branch is blank,
// then the default remote branch will be used. If the branch is "HEAD" and
// revision is empty, an impossible update is assumed.
func (g *gitrepo) Checkout(branch, tag, revision string) (WorkingCopy, error) {
	if branch == "HEAD" && revision == "" {
		return nil, fmt.Errorf("cannot update %q as it has been previously fetched with -tag or -revision. Please use gvt delete then fetch again.", g.url)
	}
	if !atMostOne(tag, revision) {
		return nil, fmt.Errorf("only one of tag or revision may be supplied")
	}
	if !atMostOne(branch, tag) {
		return nil, fmt.Errorf("only one of branch or tag may be supplied")
	}
	dir, err := mktmp()
	if err != nil {
		return nil, err
	}
	wc := workingcopy{
		path: dir,
	}

	quiet := false
	args := []string{
		"clone",
		"-q", // silence progress report to stderr
		g.url,
		dir,
	}
	if branch != "" && branch != "HEAD" {
		args = append(args, "--branch", branch, "--single-branch")
	}
	if tag != "" {
		quiet = true // git REALLY wants to tell you how awesome 'detached HEAD' is...
		args = append(args, "--branch", tag, "--single-branch")
		args = append(args, "--depth", "1")
	}
	if revision == "" {
		args = append(args, "--depth", "1")
	}

	if quiet {
		err = runQuiet("git", args...)
	} else {
		_, err = run("git", args...)
	}
	if err != nil {
		wc.Destroy()
		return nil, err
	}

	if revision != "" {
		if err := runOutPath(os.Stderr, dir, "git", "checkout", "-q", revision); err != nil {
			wc.Destroy()
			return nil, err
		}
	}

	return &GitClone{wc}, nil
}

type workingcopy struct {
	path string
}

func (w workingcopy) Dir() string { return w.path }

func (w workingcopy) Destroy() error {
	return fileutils.RemoveAll(w.path)
}

// GitClone is a git WorkingCopy.
type GitClone struct {
	workingcopy
}

func (g *GitClone) Revision() (string, error) {
	rev, err := runPath(g.path, "git", "rev-parse", "HEAD")
	return strings.TrimSpace(string(rev)), err
}

func (g *GitClone) Branch() (string, error) {
	rev, err := runPath(g.path, "git", "rev-parse", "--abbrev-ref", "HEAD")
	return strings.TrimSpace(string(rev)), err
}

// Hgrepo returns a RemoteRepo representing a remote git repository.
func Hgrepo(u *url.URL, insecure bool, schemes ...string) (RemoteRepo, error) {
	if len(schemes) == 0 {
		schemes = []string{"https", "http"}
	}
	url, err := probeHgUrl(u, insecure, schemes)
	if err != nil {
		return nil, err
	}
	return &hgrepo{
		url: url,
	}, nil
}

// hgrepo is a Mercurial repo.
type hgrepo struct {

	// remote repository url, see man 1 hg
	url string
}

func (h *hgrepo) URL() string  { return h.url }
func (h *hgrepo) Type() string { return "hg" }

func (h *hgrepo) Checkout(branch, tag, revision string) (WorkingCopy, error) {
	if !atMostOne(tag, revision) {
		return nil, fmt.Errorf("only one of tag or revision may be supplied")
	}
	dir, err := mktmp()
	if err != nil {
		return nil, err
	}
	args := []string{
		"clone",
		h.url,
		dir,
		"--noninteractive",
	}

	if branch != "" {
		args = append(args, "--branch", branch)
	}
	if err := runOut(os.Stderr, "hg", args...); err != nil {
		fileutils.RemoveAll(dir)
		return nil, err
	}
	if revision != "" {
		if err := runOut(os.Stderr, "hg", "--cwd", dir, "update", "-r", revision); err != nil {
			fileutils.RemoveAll(dir)
			return nil, err
		}
	}

	return &HgClone{
		workingcopy{
			path: dir,
		},
	}, nil
}

// HgClone is a mercurial WorkingCopy.
type HgClone struct {
	workingcopy
}

func (h *HgClone) Revision() (string, error) {
	rev, err := run("hg", "--cwd", h.path, "id", "-i")
	return strings.TrimSpace(string(rev)), err
}

func (h *HgClone) Branch() (string, error) {
	rev, err := run("hg", "--cwd", h.path, "branch")
	return strings.TrimSpace(string(rev)), err
}

// Bzrrepo returns a RemoteRepo representing a remote bzr repository.
func Bzrrepo(url string) (RemoteRepo, error) {
	if err := probeBzrUrl(url); err != nil {
		return nil, err
	}
	return &bzrrepo{
		url: url,
	}, nil
}

// bzrrepo is a bzr RemoteRepo.
type bzrrepo struct {

	// remote repository url
	url string
}

func (b *bzrrepo) URL() string {
	return b.url
}

func (b *bzrrepo) Type() string {
	return "bzr"
}

func (b *bzrrepo) Checkout(branch, tag, revision string) (WorkingCopy, error) {
	if !atMostOne(tag, revision) {
		return nil, fmt.Errorf("only one of tag or revision may be supplied")
	}
	dir, err := mktmp()
	if err != nil {
		return nil, err
	}
	wc := filepath.Join(dir, "wc")
	if err := runOut(os.Stderr, "bzr", "branch", b.url, wc); err != nil {
		fileutils.RemoveAll(dir)
		return nil, err
	}

	return &BzrClone{
		workingcopy{
			path: wc,
		},
	}, nil
}

// BzrClone is a bazaar WorkingCopy.
type BzrClone struct {
	workingcopy
}

func (b *BzrClone) Revision() (string, error) {
	return "1", nil
}

func (b *BzrClone) Branch() (string, error) {
	return "master", nil
}

func (b *BzrClone) Destroy() error {
	if err := (workingcopy{b.path}).Destroy(); err != nil {
		return err
	}
	parent := filepath.Dir(b.path)
	return os.Remove(parent)
}

func cleanPath(path string) error {
	if files, _ := ioutil.ReadDir(path); len(files) > 0 || filepath.Base(path) == "vendor" {
		return nil
	}
	parent := filepath.Dir(path)
	if err := fileutils.RemoveAll(path); err != nil {
		return err
	}
	return cleanPath(parent)
}

func mktmp() (string, error) {
	return ioutil.TempDir("", "gvt-")
}

func run(c string, args ...string) ([]byte, error) {
	var buf bytes.Buffer
	err := runOut(&buf, c, args...)
	return buf.Bytes(), err
}

func runOut(w io.Writer, c string, args ...string) error {
	cmd := exec.Command(c, args...)
	cmd.Stdin = nil
	cmd.Stdout = w
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

func runQuiet(c string, args ...string) error {
	cmd := exec.Command(c, args...)
	cmd.Stdin = nil
	cmd.Stdout = nil
	cmd.Stderr = nil
	return cmd.Run()
}

func runPath(path string, c string, args ...string) ([]byte, error) {
	var buf bytes.Buffer
	err := runOutPath(&buf, path, c, args...)
	return buf.Bytes(), err
}

func runOutPath(w io.Writer, path string, c string, args ...string) error {
	cmd := exec.Command(c, args...)
	cmd.Dir = path
	cmd.Stdin = nil
	cmd.Stdout = w
	cmd.Stderr = os.Stderr
	return cmd.Run()
}

// atMostOne returns true if no more than one string supplied is not empty.
func atMostOne(args ...string) bool {
	var c int
	for _, arg := range args {
		if arg != "" {
			c++
		}
	}
	return c < 2
}

// oneof returns the first non empty string
func oneOf(args ...string) string {
	for _, arg := range args {
		if arg != "" {
			return arg
		}
	}
	return ""
}
