// Copyright 2018 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.

package github

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"

	"cmd/go/internal/modfetch/codehost"
	web "cmd/go/internal/web2"
)

func Lookup(path string) (codehost.Repo, error) {
	f := strings.Split(path, "/")
	if len(f) < 3 || f[0] != "github.com" {
		return nil, fmt.Errorf("github repo must be github.com/org/project")
	}

	// Check for moved, renamed, or incorrect case in repository.
	// Otherwise the API calls all appear to work.
	// We need to do better here, but it's unclear exactly what.
	var data struct {
		FullName string `json:"full_name"`
	}
	err := web.Get("https://api.github.com/repos/"+url.PathEscape(f[1])+"/"+url.PathEscape(f[2]), web.DecodeJSON(&data))
	if err != nil {
		return nil, err
	}
	myFullName := f[1] + "/" + f[2]
	if myFullName != data.FullName {
		why := "moved"
		if strings.EqualFold(myFullName, data.FullName) {
			why = "wrong case"
		}
		return nil, fmt.Errorf("module path of repo is github.com/%s, not %s (%s)", data.FullName, path, why)
	}

	return newRepo(f[1], f[2]), nil
}

func newRepo(owner, repository string) codehost.Repo {
	return &repo{owner, repository}
}

type repo struct {
	owner string
	repo  string
}

func (r *repo) Root() string {
	return "github.com/" + r.owner + "/" + r.repo
}

func (r *repo) Tags(prefix string) ([]string, error) {
	var tags []string
	u := "https://api.github.com/repos/" + url.PathEscape(r.owner) + "/" + url.PathEscape(r.repo) + "/tags"
	for u != "" {
		var data []struct {
			Name string
		}
		var hdr http.Header
		err := web.Get(u, web.Header(&hdr), web.DecodeJSON(&data))
		if err != nil {
			return nil, err
		}
		for _, t := range data {
			if strings.HasPrefix(t.Name, prefix) {
				tags = append(tags, t.Name)
			}
		}
		last := u
		u = ""
		for _, link := range parseLinks(hdr.Get("Link")) {
			if link.Rel == "next" && link.URL != last {
				u = link.URL
			}
		}
	}
	return tags, nil
}

func (r *repo) LatestAt(t time.Time, branch string) (*codehost.RevInfo, error) {
	var commits []struct {
		SHA    string
		Commit struct {
			Committer struct {
				Date string
			}
		}
	}
	err := web.Get(
		"https://api.github.com/repos/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/commits?sha="+url.QueryEscape(branch)+"&until="+url.QueryEscape(t.UTC().Format("2006-01-02T15:04:05Z"))+"&per_page=2",
		web.DecodeJSON(&commits),
	)
	if err != nil {
		return nil, err
	}
	if len(commits) == 0 {
		return nil, fmt.Errorf("no commits")
	}
	d, err := time.Parse("2006-01-02T15:04:05Z", commits[0].Commit.Committer.Date)
	if err != nil {
		return nil, err
	}

	info := &codehost.RevInfo{
		Name:  commits[0].SHA,
		Short: codehost.ShortenSHA1(commits[0].SHA),
		Time:  d,
	}
	return info, nil
}

func (r *repo) Stat(rev string) (*codehost.RevInfo, error) {
	var tag string
	if !codehost.AllHex(rev) {
		// Resolve tag to rev
		tag = rev
		var ref struct {
			Ref    string
			Object struct {
				Type string
				SHA  string
				URL  string
			}
		}
		err := web.Get(
			"https://api.github.com/repos/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/git/refs/tags/"+tag,
			web.DecodeJSON(&ref),
		)
		if err != nil {
			return nil, err
		}
		switch ref.Object.Type {
		default:
			return nil, fmt.Errorf("invalid tag %q: not a commit or tag (%q)", tag, ref.Object.Type)

		case "commit":
			rev = ref.Object.SHA

		case "tag":
			var info struct {
				Object struct {
					SHA  string
					Type string
				}
			}
			err = web.Get(
				ref.Object.URL,
				web.DecodeJSON(&info),
			)
			if err != nil {
				return nil, err
			}
			if info.Object.Type != "commit" {
				return nil, fmt.Errorf("invalid annotated tag %q: not a commit (%q)", tag, info.Object.Type)
			}
			rev = info.Object.SHA
		}
		if rev == "" {
			return nil, fmt.Errorf("invalid tag %q: missing SHA in GitHub response", tag)
		}
	}

	var commits []struct {
		SHA    string
		Commit struct {
			Committer struct {
				Date string
			}
		}
	}
	err := web.Get(
		"https://api.github.com/repos/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/commits?sha="+url.QueryEscape(rev)+"&per_page=2",
		web.DecodeJSON(&commits),
	)
	if err != nil {
		return nil, err
	}
	if len(commits) == 0 {
		return nil, fmt.Errorf("no commits")
	}
	if !strings.HasPrefix(commits[0].SHA, rev) {
		return nil, fmt.Errorf("wrong rev returned by server")
	}
	d, err := time.Parse("2006-01-02T15:04:05Z", commits[0].Commit.Committer.Date)
	if err != nil {
		return nil, err
	}
	info := &codehost.RevInfo{
		Name:    commits[0].SHA,
		Short:   codehost.ShortenSHA1(commits[0].SHA),
		Version: tag,
		Time:    d,
	}
	return info, nil
}

func (r *repo) ReadFile(rev, file string, maxSize int64) ([]byte, error) {
	var meta struct {
		Type        string
		Size        int64
		Name        string
		DownloadURL string `json:"download_url"`
	}
	err := web.Get(
		"https://api.github.com/repos/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/contents/"+url.PathEscape(file)+"?ref="+url.QueryEscape(rev),
		web.DecodeJSON(&meta),
	)
	if err != nil {
		return nil, err
	}
	if meta.DownloadURL == "" {
		return nil, fmt.Errorf("no download URL")
	}

	// TODO: Use maxSize.
	var body []byte
	err = web.Get(meta.DownloadURL, web.ReadAllBody(&body))
	if err != nil {
		return nil, err
	}
	return body, nil
}

func (r *repo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) {
	// TODO: Make web.Get copy to file for us, with limit.
	var body io.ReadCloser
	err = web.Get(
		"https://api.github.com/repos/"+url.PathEscape(r.owner)+"/"+url.PathEscape(r.repo)+"/zipball/"+url.PathEscape(rev),
		web.Body(&body),
	)
	if err != nil {
		if body != nil {
			body.Close()
		}
		return nil, "", err
	}
	return body, "", nil
}

type link struct {
	URL string
	Rel string
}

func parseLinks(text string) []link {
	var links []link
	for text != "" {
		text = strings.TrimSpace(text)
		if !strings.HasPrefix(text, "<") {
			break
		}
		i := strings.Index(text, ">")
		if i < 0 {
			break
		}
		u := text[1:i]
		text = strings.TrimSpace(text[i+1:])
	Attrs:
		for strings.HasPrefix(text, ";") {
			text = text[1:]
			j := 0
			for j < len(text) && text[j] != '=' {
				if text[j] == ',' || text[j] == ';' || text[j] == '"' {
					break Attrs
				}
				j++
			}
			if j >= len(text) {
				break Attrs
			}
			key := strings.TrimSpace(text[:j])
			text = strings.TrimSpace(text[j+1:])
			var val string
			if len(text) > 0 && text[0] == '"' {
				k := 1
				for k < len(text) && text[k] != '"' {
					if text[k] == '\\' && k+1 < len(text) {
						k++
					}
					k++
				}
				if k >= len(text) {
					break Attrs
				}
				val, text = text[1:k], text[k+1:]
			} else {
				k := 0
				for k < len(text) && text[k] != ';' && text[k] != ',' {
					if text[k] == '"' {
						break Attrs
					}
					k++
				}
				if k >= len(text) {
					break Attrs
				}
				val, text = text[:k], text[k:]
			}
			if key == "rel" {
				links = append(links, link{URL: u, Rel: strings.TrimSpace(val)})
			}
		}
		text = strings.TrimSpace(text)
		if !strings.HasPrefix(text, ",") {
			break
		}
		text = text[1:]
	}
	return links
}
