// Copyright 2013 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 or at
// https://developers.google.com/open-source/licenses/bsd.

package gosrc

import (
	"context"
	"errors"
	"net/http"
	"net/url"
	"regexp"
	"strings"
)

func init() {
	addService(&service{
		pattern:         regexp.MustCompile(`^code\.google\.com/(?P<pr>[pr])/(?P<repo>[a-z0-9\-]+)(:?\.(?P<subrepo>[a-z0-9\-]+))?(?P<dir>/[a-z0-9A-Z_.\-/]+)?$`),
		prefix:          "code.google.com/",
		get:             getGoogleDir,
		getPresentation: getGooglePresentation,
	})
}

var (
	googleRepoRe     = regexp.MustCompile(`id="checkoutcmd">(hg|git|svn)`)
	googleRevisionRe = regexp.MustCompile(`<h2>(?:[^ ]+ - )?Revision *([^:]+):`)
	googleEtagRe     = regexp.MustCompile(`^(hg|git|svn)-`)
	googleFileRe     = regexp.MustCompile(`<li><a href="([^"]+)"`)
)

func checkGoogleRedir(ctx context.Context, c *httpClient, match map[string]string) error {
	resp, err := c.getNoFollow(expand("https://code.google.com/{pr}/{repo}/", match))
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode == http.StatusOK {
		return nil
	}
	if resp.StatusCode == http.StatusMovedPermanently {
		if u, err := url.Parse(resp.Header.Get("Location")); err == nil {
			p := u.Host + u.Path + match["dir"]
			return NotFoundError{Message: "Project moved", Redirect: p}
		}
	}
	return c.err(resp)
}

func getGoogleDir(ctx context.Context, client *http.Client, match map[string]string, savedEtag string) (*Directory, error) {
	setupGoogleMatch(match)
	c := &httpClient{client: client}

	if err := checkGoogleRedir(ctx, c, match); err != nil {
		return nil, err
	}

	if m := googleEtagRe.FindStringSubmatch(savedEtag); m != nil {
		match["vcs"] = m[1]
	} else if err := getGoogleVCS(ctx, c, match); err != nil {
		return nil, err
	}

	// Scrape the repo browser to find the project revision and individual Go files.
	p, err := c.getBytes(ctx, expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/", match))
	if err != nil {
		return nil, err
	}

	var etag string
	m := googleRevisionRe.FindSubmatch(p)
	if m == nil {
		return nil, errors.New("Could not find revision for " + match["importPath"])
	}
	etag = expand("{vcs}-{0}", match, string(m[1]))
	if etag == savedEtag {
		return nil, NotModifiedError{}
	}

	var subdirs []string
	var files []*File
	var dataURLs []string
	for _, m := range googleFileRe.FindAllSubmatch(p, -1) {
		fname := string(m[1])
		switch {
		case strings.HasSuffix(fname, "/"):
			fname = fname[:len(fname)-1]
			if isValidPathElement(fname) {
				subdirs = append(subdirs, fname)
			}
		case isDocFile(fname):
			files = append(files, &File{Name: fname, BrowseURL: expand("http://code.google.com/{pr}/{repo}/source/browse{dir}/{0}{query}", match, fname)})
			dataURLs = append(dataURLs, expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/{0}", match, fname))
		}
	}

	if err := c.getFiles(ctx, dataURLs, files); err != nil {
		return nil, err
	}

	var projectURL string
	if match["subrepo"] == "" {
		projectURL = expand("https://code.google.com/{pr}/{repo}/", match)
	} else {
		projectURL = expand("https://code.google.com/{pr}/{repo}/source/browse?repo={subrepo}", match)
	}

	return &Directory{
		BrowseURL:   expand("http://code.google.com/{pr}/{repo}/source/browse{dir}/{query}", match),
		Etag:        etag,
		Files:       files,
		LineFmt:     "%s#%d",
		ProjectName: expand("{repo}{dot}{subrepo}", match),
		ProjectRoot: expand("code.google.com/{pr}/{repo}{dot}{subrepo}", match),
		ProjectURL:  projectURL,
		VCS:         match["vcs"],
	}, nil
}

func setupGoogleMatch(match map[string]string) {
	if s := match["subrepo"]; s != "" {
		match["dot"] = "."
		match["query"] = "?repo=" + s
	} else {
		match["dot"] = ""
		match["query"] = ""
	}
}

func getGoogleVCS(ctx context.Context, c *httpClient, match map[string]string) error {
	// Scrape the HTML project page to find the VCS.
	p, err := c.getBytes(ctx, expand("http://code.google.com/{pr}/{repo}/source/checkout", match))
	if err != nil {
		return err
	}
	m := googleRepoRe.FindSubmatch(p)
	if m == nil {
		return NotFoundError{Message: "Could not find VCS on Google Code project page."}
	}
	match["vcs"] = string(m[1])
	return nil
}

func getGooglePresentation(ctx context.Context, client *http.Client, match map[string]string) (*Presentation, error) {
	c := &httpClient{client: client}

	setupGoogleMatch(match)
	if err := getGoogleVCS(ctx, c, match); err != nil {
		return nil, err
	}

	rawBase, err := url.Parse(expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/", match))
	if err != nil {
		return nil, err
	}

	p, err := c.getBytes(ctx, expand("http://{subrepo}{dot}{repo}.googlecode.com/{vcs}{dir}/{file}", match))
	if err != nil {
		return nil, err
	}

	b := &presBuilder{
		data:     p,
		filename: match["file"],
		fetch: func(fnames []string) ([]*File, error) {
			var files []*File
			var dataURLs []string
			for _, fname := range fnames {
				u, err := rawBase.Parse(fname)
				if err != nil {
					return nil, err
				}
				files = append(files, &File{Name: fname})
				dataURLs = append(dataURLs, u.String())
			}
			err := c.getFiles(ctx, dataURLs, files)
			return files, err
		},
		resolveURL: func(fname string) string {
			u, err := rawBase.Parse(fname)
			if err != nil {
				return "/notfound"
			}
			return u.String()
		},
	}

	return b.build()
}
