// 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_.\-/]+)?$`)

// 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 = fmt.Errorf(
			"unsupported import path; should be %q\n"+
				"Run goinstall with -fix to gofix the code.",
			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()
}
