package vendor

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

	"github.com/constabulary/gb/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 taken from. It should
	// only be called after Clone.
	URL() 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 and cleans path to 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
}

// 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 {
	if err := fileutils.RemoveAll(w.path); err != nil {
		return err
	}
	parent := filepath.Dir(w.path)
	return cleanPath(parent)
}

// 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) 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) 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 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 mkdir(path string) error {
	return os.MkdirAll(path, 0755)
}

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 ""
}
