// Copyright 2017 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 sourcecache provides a cache of code found in Git repositories.
// It takes directly to the Gerrit instance at go.googlesource.com.
// If RegisterGitMirrorDial is called, it will first try to get code from gitmirror before falling back on Gerrit.
package sourcecache

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"time"

	"golang.org/x/build/internal/lru"
	"golang.org/x/build/internal/singleflight"
	"golang.org/x/build/internal/spanlog"
)

var processStartTime = time.Now()

var sourceGroup singleflight.Group

var sourceCache = lru.New(40) // repo-rev -> source

// source is the cache entry type for sourceCache.
type source struct {
	Tgz    []byte // Source tarball bytes.
	TooBig bool
}

// GetSourceTgz returns a Reader that provides a tgz of the requested source revision.
// repo is go.googlesource.com repo ("go", "net", and so on).
// rev is git revision.
//
// An error of type TooBigError is returned if the compressed tarball exceeds a size that
// on 2021-11-22 was deemed to be enough to meet expected legitimate future needs for a while.
// See golang.org/issue/46379.
func GetSourceTgz(sl spanlog.Logger, repo, rev string) (tgz io.Reader, err error) {
	sp := sl.CreateSpan("get_source", repo+"@"+rev)
	defer func() { sp.Done(err) }()

	key := fmt.Sprintf("%v-%v", repo, rev)
	v, err, _ := sourceGroup.Do(key, func() (any, error) {
		if src, ok := sourceCache.Get(key); ok {
			return src, nil
		}

		if gitMirrorClient != nil {
			sp := sl.CreateSpan("get_source_from_gitmirror")
			src, err := getSourceTgzFromGitMirror(repo, rev)
			if err == nil {
				sourceCache.Add(key, src)
				sp.Done(nil)
				return src, nil
			}
			log.Printf("Error fetching source %s/%s from gitmirror (after %v uptime): %v",
				repo, rev, time.Since(processStartTime), err)
			sp.Done(errors.New("timeout"))
		}

		sp := sl.CreateSpan("get_source_from_gerrit", fmt.Sprintf("%v from gerrit", key))
		src, err := getSourceTgzFromGerrit(repo, rev)
		sp.Done(err)
		if err == nil {
			sourceCache.Add(key, src)
		}
		return src, err
	})
	if err != nil {
		return nil, err
	}
	if v.(source).TooBig {
		return nil, TooBigError{Repo: repo, Rev: rev, Limit: maxSize(repo)}
	}
	return bytes.NewReader(v.(source).Tgz), nil
}

// TooBigError is the error returned when the source revision is considered too big.
type TooBigError struct {
	Repo  string
	Rev   string
	Limit int64 // Max size in bytes.
}

func (e TooBigError) Error() string {
	return fmt.Sprintf("rejected because compressed tarball of repository go.googlesource.com/%s at revision %s exceeded a limit of %d MB; see golang.org/issue/46379",
		e.Repo, e.Rev, e.Limit/1024/1024)
}

var gitMirrorClient *http.Client

// RegisterGitMirrorDial registers a dial function which will be used to reach gitmirror.
// If used, this function must be called before GetSourceTgz.
func RegisterGitMirrorDial(dial func(context.Context) (net.Conn, error)) {
	gitMirrorClient = &http.Client{
		Timeout: 30 * time.Second,
		Transport: &http.Transport{
			IdleConnTimeout: 30 * time.Second,
			DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
				return dial(ctx)
			},
		},
	}
}

var gerritHTTPClient = &http.Client{
	Timeout: 30 * time.Second,
}

func getSourceTgzFromGerrit(repo, rev string) (source, error) {
	return getSourceTgzFromURL(gerritHTTPClient, "gerrit", repo, rev, "https://go.googlesource.com/"+repo+"/+archive/"+rev+".tar.gz")
}

func getSourceTgzFromGitMirror(repo, rev string) (src source, err error) {
	for i := range 2 { // two tries; different pods maybe?
		if i > 0 {
			time.Sleep(1 * time.Second)
		}
		// The "gitmirror" hostname is unused:
		src, err = getSourceTgzFromURL(gitMirrorClient, "gitmirror", repo, rev, "http://gitmirror/"+repo+".tar.gz?rev="+rev)
		if err == nil {
			return src, nil
		}
		if tr, ok := http.DefaultTransport.(*http.Transport); ok {
			tr.CloseIdleConnections()
		}
	}
	return source{}, err
}

// getSourceTgzFromURL fetches a source tarball from url.
// If url serves more than maxSize bytes, it stops short.
func getSourceTgzFromURL(hc *http.Client, service, repo, rev, url string) (source, error) {
	res, err := hc.Get(url)
	if err != nil {
		return source{}, fmt.Errorf("fetching %s/%s from %s: %v", repo, rev, service, err)
	}
	defer res.Body.Close()
	if res.StatusCode/100 != 2 {
		slurp, _ := io.ReadAll(io.LimitReader(res.Body, 4<<10))
		return source{}, fmt.Errorf("fetching %s/%s from %s: %v; body: %s", repo, rev, service, res.Status, slurp)
	}
	// See golang.org/issue/11224 for a discussion on tree filtering.
	b, err := io.ReadAll(io.LimitReader(res.Body, maxSize(repo)+1))
	if int64(len(b)) > maxSize(repo) && err == nil {
		return source{TooBig: true}, nil
	}
	if err != nil {
		return source{}, fmt.Errorf("reading %s/%s from %s: %v", repo, rev, service, err)
	}
	return source{Tgz: b}, nil
}

// maxSize controls artificial limits on how big of a compressed source tarball
// this package is willing to accept. It's expected humans may need to manage
// these limits every couple of years for the evolving needs of the Go project,
// and ideally not much more often.
//
// repo is a go.googlesource.com repo ("go", "net", and so on).
func maxSize(repo string) int64 {
	switch repo {
	default:
		// As of 2021-11-22, a compressed tarball of Go source is 23 MB,
		// x/net is 1.2 MB,
		// x/build is 1.1 MB,
		// x/tools is 2.9 MB.
		return 100 << 20
	case "website":
		// In 2021, all content in x/blog (52 MB) and x/talks (74 MB) moved
		// to x/website. This makes x/website an outlier, with a compressed
		// tarball size of 135 MB. Give it some room to grow from there.
		return 200 << 20
	}
}
