// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Download remote packages.

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strconv"
	"strings"
)

const dashboardURL = "http://godashboard.appspot.com/package"

// maybeReportToDashboard reports path to dashboard unless
// -dashboard=false is on command line.  It ignores errors.
func maybeReportToDashboard(path string) {
	// if -dashboard=false was on command line, do nothing
	if !*reportToDashboard {
		return
	}

	// otherwise lob url to dashboard
	r, _ := http.Post(dashboardURL, "application/x-www-form-urlencoded", strings.NewReader("path="+path))
	if r != nil && r.Body != nil {
		r.Body.Close()
	}
}

// a vcs represents a version control system
// like Mercurial, Git, or Subversion.
type vcs struct {
	name          string
	cmd           string
	metadir       string
	checkout      string
	clone         string
	update        string
	updateRevFlag string
	pull          string
	pullForceFlag string
	tagList       string
	tagListRe     *regexp.Regexp
	check         string
	protocols     []string
	suffix        string
}

func (v *vcs) String() string {
	return v.name
}

var vcsMap = map[string]*vcs{
	"hg": {
		name:      "Mercurial",
		cmd:       "hg",
		metadir:   ".hg",
		checkout:  "checkout",
		clone:     "clone",
		update:    "update",
		pull:      "pull",
		tagList:   "tags",
		tagListRe: regexp.MustCompile("([^ ]+)[^\n]+\n"),
		check:     "identify",
		protocols: []string{"https", "http"},
		suffix:    ".hg",
	},

	"git": {
		name:      "Git",
		cmd:       "git",
		metadir:   ".git",
		checkout:  "checkout",
		clone:     "clone",
		update:    "pull",
		pull:      "fetch",
		tagList:   "tag",
		tagListRe: regexp.MustCompile("([^\n]+)\n"),
		check:     "ls-remote",
		protocols: []string{"git", "https", "http"},
		suffix:    ".git",
	},

	"svn": {
		name:      "Subversion",
		cmd:       "svn",
		metadir:   ".svn",
		checkout:  "checkout",
		clone:     "checkout",
		update:    "update",
		check:     "info",
		protocols: []string{"https", "http", "svn"},
		suffix:    ".svn",
	},

	"bzr": {
		name:          "Bazaar",
		cmd:           "bzr",
		metadir:       ".bzr",
		checkout:      "update",
		clone:         "branch",
		update:        "update",
		updateRevFlag: "-r",
		pull:          "pull",
		pullForceFlag: "--overwrite",
		tagList:       "tags",
		tagListRe:     regexp.MustCompile("([^ ]+)[^\n]+\n"),
		check:         "info",
		protocols:     []string{"https", "http", "bzr"},
		suffix:        ".bzr",
	},
}

type RemoteRepo interface {
	// IsCheckedOut returns whether this repository is checked
	// out inside the given srcDir (eg, $GOPATH/src).
	IsCheckedOut(srcDir string) bool

	// Repo returns the information about this repository: its url,
	// the part of the import path that forms the repository root,
	// and the version control system it uses. It may discover this
	// information by using the supplied client to make HTTP requests.
	Repo(*http.Client) (url, root string, vcs *vcs, err error)
}

type host struct {
	pattern *regexp.Regexp
	repo    func(repo string) (RemoteRepo, error)
}

var knownHosts = []host{
	{
		regexp.MustCompile(`^code\.google\.com/p/([a-z0-9\-]+(\.[a-z0-9\-]+)?)(/[a-z0-9A-Z_.\-/]+)?$`),
		matchGoogleRepo,
	},
	{
		regexp.MustCompile(`^(github\.com/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]+)?$`),
		matchGithubRepo,
	},
	{
		regexp.MustCompile(`^(bitbucket\.org/[a-z0-9A-Z_.\-]+/[a-z0-9A-Z_.\-]+)(/[a-z0-9A-Z_.\-/]+)?$`),
		matchBitbucketRepo,
	},
	{
		regexp.MustCompile(`^(launchpad\.net/([a-z0-9A-Z_.\-]+(/[a-z0-9A-Z_.\-]+)?|~[a-z0-9A-Z_.\-]+/(\+junk|[a-z0-9A-Z_.\-]+)/[a-z0-9A-Z_.\-]+))(/[a-z0-9A-Z_.\-/]+)?$`),
		matchLaunchpadRepo,
	},
}

// baseRepo is the base implementation of RemoteRepo.
type baseRepo struct {
	url, root string
	vcs       *vcs
}

func (r *baseRepo) Repo(*http.Client) (url, root string, vcs *vcs, err error) {
	return r.url, r.root, r.vcs, nil
}

// IsCheckedOut reports whether the repo root inside srcDir contains a
// repository metadir. It updates the baseRepo's vcs field if necessary.
func (r *baseRepo) IsCheckedOut(srcDir string) bool {
	pkgPath := filepath.Join(srcDir, r.root)
	if r.vcs == nil {
		for _, vcs := range vcsMap {
			if isDir(filepath.Join(pkgPath, vcs.metadir)) {
				r.vcs = vcs
				return true
			}
		}
		return false
	}
	return isDir(filepath.Join(pkgPath, r.vcs.metadir))
}

// matchGithubRepo handles matches for github.com repositories.
func matchGithubRepo(root string) (RemoteRepo, error) {
	if strings.HasSuffix(root, ".git") {
		return nil, errors.New("path must not include .git suffix")
	}
	return &baseRepo{"http://" + root + ".git", root, vcsMap["git"]}, nil
}

// matchLaunchpadRepo handles matches for launchpad.net repositories.
func matchLaunchpadRepo(root string) (RemoteRepo, error) {
	return &baseRepo{"https://" + root, root, vcsMap["bzr"]}, nil
}

// matchGoogleRepo matches repos like "code.google.com/p/repo.subrepo/path".
func matchGoogleRepo(id string) (RemoteRepo, error) {
	root := "code.google.com/p/" + id
	return &googleRepo{baseRepo{"https://" + root, root, nil}}, nil
}

// googleRepo implements a RemoteRepo that discovers a Google Code
// repository's VCS type by scraping the code.google.com source checkout page.
type googleRepo struct{ baseRepo }

var googleRepoRe = regexp.MustCompile(`id="checkoutcmd">(hg|git|svn)`)

func (r *googleRepo) Repo(client *http.Client) (url, root string, vcs *vcs, err error) {
	if r.vcs != nil {
		return r.url, r.root, r.vcs, nil
	}

	// Use the code.google.com source checkout page to find the VCS type.
	const prefix = "code.google.com/p/"
	p := strings.SplitN(r.root[len(prefix):], ".", 2)
	u := fmt.Sprintf("https://%s%s/source/checkout", prefix, p[0])
	if len(p) == 2 {
		u += fmt.Sprintf("?repo=%s", p[1])
	}
	resp, err := client.Get(u)
	if err != nil {
		return "", "", nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return "", "", nil, fmt.Errorf("fetching %s: %v", u, resp.Status)
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", "", nil, fmt.Errorf("fetching %s: %v", u, err)
	}

	// Scrape result for vcs details.
	m := googleRepoRe.FindSubmatch(b)
	if len(m) == 2 {
		if v := vcsMap[string(m[1])]; v != nil {
			r.vcs = v
			return r.url, r.root, r.vcs, nil
		}
	}

	return "", "", nil, errors.New("could not detect googlecode vcs")
}

// matchBitbucketRepo handles matches for all bitbucket.org repositories.
func matchBitbucketRepo(root string) (RemoteRepo, error) {
	if strings.HasSuffix(root, ".git") {
		return nil, errors.New("path must not include .git suffix")
	}
	return &bitbucketRepo{baseRepo{root: root}}, nil
}

// bitbucketRepo implements a RemoteRepo that uses the BitBucket API to
// discover the repository's VCS type.
type bitbucketRepo struct{ baseRepo }

func (r *bitbucketRepo) Repo(client *http.Client) (url, root string, vcs *vcs, err error) {
	if r.vcs != nil && r.url != "" {
		return r.url, r.root, r.vcs, nil
	}

	// Use the BitBucket API to find which kind of repository this is.
	const apiUrl = "https://api.bitbucket.org/1.0/repositories/"
	resp, err := client.Get(apiUrl + strings.SplitN(r.root, "/", 2)[1])
	if err != nil {
		return "", "", nil, fmt.Errorf("BitBucket API: %v", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return "", "", nil, fmt.Errorf("BitBucket API: %v", resp.Status)
	}
	var response struct {
		Vcs string `json:"scm"`
	}
	err = json.NewDecoder(resp.Body).Decode(&response)
	if err != nil {
		return "", "", nil, fmt.Errorf("BitBucket API: %v", err)
	}
	switch response.Vcs {
	case "git":
		r.url = "http://" + r.root + ".git"
	case "hg":
		r.url = "http://" + r.root
	default:
		return "", "", nil, errors.New("unsupported bitbucket vcs: " + response.Vcs)
	}
	if r.vcs = vcsMap[response.Vcs]; r.vcs == nil {
		panic("vcs is nil when it should not be")
	}
	return r.url, r.root, r.vcs, nil
}

// findPublicRepo checks whether importPath is a well-formed path for one of
// the supported code hosting sites and, if so, returns a RemoteRepo.
func findPublicRepo(importPath string) (RemoteRepo, error) {
	for _, host := range knownHosts {
		if hm := host.pattern.FindStringSubmatch(importPath); hm != nil {
			return host.repo(hm[1])
		}
	}
	return nil, nil
}

// findAnyRepo matches import paths with a repo suffix (.git, etc).
func findAnyRepo(importPath string) RemoteRepo {
	for _, v := range vcsMap {
		i := strings.Index(importPath+"/", v.suffix+"/")
		if i < 0 {
			continue
		}
		if !strings.Contains(importPath[:i], "/") {
			continue // don't match vcs suffix in the host name
		}
		return &anyRepo{
			baseRepo{
				root: importPath[:i] + v.suffix,
				vcs:  v,
			},
			importPath[:i],
		}
	}
	return nil
}

// anyRepo implements an discoverable remote repo with a suffix (.git, etc).
type anyRepo struct {
	baseRepo
	rootWithoutSuffix string
}

func (r *anyRepo) Repo(*http.Client) (url, root string, vcs *vcs, err error) {
	if r.url != "" {
		return r.url, r.root, r.vcs, nil
	}
	url, err = r.vcs.findURL(r.rootWithoutSuffix)
	if url == "" && err == nil {
		err = fmt.Errorf("couldn't find %s repository", r.vcs.name)
	}
	if err != nil {
		return "", "", nil, err
	}
	r.url = url
	return r.url, r.root, r.vcs, nil
}

// findURL finds the URL for a given repo root by trying each combination of
// protocol and suffix in series.
func (v *vcs) findURL(root string) (string, error) {
	for _, proto := range v.protocols {
		for _, suffix := range []string{"", v.suffix} {
			url := proto + "://" + root + suffix
			out, err := exec.Command(v.cmd, v.check, url).CombinedOutput()
			if err == nil {
				printf("find %s: found %s\n", root, url)
				return url, nil
			}
			printf("findURL(%s): %s %s %s: %v\n%s\n", root, v.cmd, v.check, url, err, out)
		}
	}
	return "", nil
}

var oldGoogleRepo = regexp.MustCompile(`^([a-z0-9\-]+)\.googlecode\.com/(svn|git|hg)(/[a-z0-9A-Z_.\-/]+)?$`)

type errOldGoogleRepo struct {
	fixedPath string
}

func (e *errOldGoogleRepo) Error() string {
	return fmt.Sprintf("unsupported import path; should be %q", e.fixedPath)
}

// download checks out or updates the specified package from the remote server.
func download(importPath, srcDir string) (public bool, err error) {
	if strings.Contains(importPath, "..") {
		err = errors.New("invalid path (contains ..)")
		return
	}

	if m := oldGoogleRepo.FindStringSubmatch(importPath); m != nil {
		fixedPath := "code.google.com/p/" + m[1] + m[3]
		err = &errOldGoogleRepo{fixedPath}
		return
	}

	repo, err := findPublicRepo(importPath)
	if err != nil {
		return false, err
	}
	if repo != nil {
		public = true
	} else {
		repo = findAnyRepo(importPath)
	}
	if repo == nil {
		err = errors.New("cannot download: " + importPath)
		return
	}
	err = checkoutRepo(srcDir, repo)
	return
}

// checkoutRepo checks out repo into srcDir (if it's not checked out already)
// and, if the -u flag is set, updates the repository.
func checkoutRepo(srcDir string, repo RemoteRepo) error {
	if !repo.IsCheckedOut(srcDir) {
		// do checkout
		url, root, vcs, err := repo.Repo(http.DefaultClient)
		if err != nil {
			return err
		}
		repoPath := filepath.Join(srcDir, root)
		parent, _ := filepath.Split(repoPath)
		if err = os.MkdirAll(parent, 0777); err != nil {
			return err
		}
		if err = run(string(filepath.Separator), nil, vcs.cmd, vcs.clone, url, repoPath); err != nil {
			return err
		}
		return vcs.updateRepo(repoPath)
	}
	if *update {
		// do update
		_, root, vcs, err := repo.Repo(http.DefaultClient)
		if err != nil {
			return err
		}
		repoPath := filepath.Join(srcDir, root)
		// Retrieve new revisions from the remote branch, if the VCS
		// supports this operation independently (e.g. svn doesn't)
		if vcs.pull != "" {
			if vcs.pullForceFlag != "" {
				if err = run(repoPath, nil, vcs.cmd, vcs.pull, vcs.pullForceFlag); err != nil {
					return err
				}
			} else if err = run(repoPath, nil, vcs.cmd, vcs.pull); err != nil {
				return err
			}
		}
		// Update to release or latest revision
		return vcs.updateRepo(repoPath)
	}
	return nil
}

// updateRepo gets a list of tags in the repository and
// checks out the tag closest to the current runtime.Version.
// If no matching tag is found, it just updates to tip.
func (v *vcs) updateRepo(repoPath string) error {
	if v.tagList == "" || v.tagListRe == nil {
		// TODO(adg): fix for svn
		return run(repoPath, nil, v.cmd, v.update)
	}

	// Get tag list.
	stderr := new(bytes.Buffer)
	cmd := exec.Command(v.cmd, v.tagList)
	cmd.Dir = repoPath
	cmd.Stderr = stderr
	out, err := cmd.Output()
	if err != nil {
		return &RunError{strings.Join(cmd.Args, " "), repoPath, out, err}
	}
	var tags []string
	for _, m := range v.tagListRe.FindAllStringSubmatch(string(out), -1) {
		tags = append(tags, m[1])
	}

	// Only use the tag component of runtime.Version.
	ver := strings.Split(runtime.Version(), " ")[0]

	// Select tag.
	if tag := selectTag(ver, tags); tag != "" {
		printf("selecting revision %q\n", tag)
		return run(repoPath, nil, v.cmd, v.checkout, v.updateRevFlag+tag)
	}

	// No matching tag found, make default selection.
	printf("selecting tip\n")
	return run(repoPath, nil, v.cmd, v.update)
}

// selectTag returns the closest matching tag for a given version.
// Closest means the latest one that is not after the current release.
// Version "release.rN" matches tags of the form "go.rN" (N being a decimal).
// Version "weekly.YYYY-MM-DD" matches tags like "go.weekly.YYYY-MM-DD".
func selectTag(goVersion string, tags []string) (match string) {
	const rPrefix = "release.r"
	if strings.HasPrefix(goVersion, rPrefix) {
		p := "go.r"
		v, err := strconv.ParseFloat(goVersion[len(rPrefix):], 64)
		if err != nil {
			return ""
		}
		var matchf float64
		for _, t := range tags {
			if !strings.HasPrefix(t, p) {
				continue
			}
			tf, err := strconv.ParseFloat(t[len(p):], 64)
			if err != nil {
				continue
			}
			if matchf < tf && tf <= v {
				match, matchf = t, tf
			}
		}
	}
	const wPrefix = "weekly."
	if strings.HasPrefix(goVersion, wPrefix) {
		p := "go.weekly."
		v := goVersion[len(wPrefix):]
		for _, t := range tags {
			if !strings.HasPrefix(t, p) {
				continue
			}
			if match < t && t[len(p):] <= v {
				match = t
			}
		}
	}
	return match
}

func isDir(dir string) bool {
	fi, err := os.Stat(dir)
	return err == nil && fi.IsDir()
}
