// Copyright 2011 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 legacydash

import (
	"bytes"
	"compress/gzip"
	"context"
	"errors"
	"fmt"
	"io"
	"math/rand"
	pathpkg "path"
	"strings"

	"cloud.google.com/go/datastore"
	"golang.org/x/build/dashboard"
	"golang.org/x/build/internal/loghash"
)

const (
	maxDatastoreStringLen = 500
)

func dsKey(kind, name string, parent *datastore.Key) *datastore.Key {
	dk := datastore.NameKey(kind, name, parent)
	dk.Namespace = "Git"
	return dk
}

// A Package describes a package that is listed on the dashboard.
type Package struct {
	Name string // "Go", "arch", "net", ...
	Path string // empty for the main Go tree, else "golang.org/x/foo"
}

func (p *Package) String() string {
	return fmt.Sprintf("%s: %q", p.Path, p.Name)
}

func (p *Package) Key() *datastore.Key {
	key := p.Path
	if key == "" {
		key = "go"
	}
	return dsKey("Package", key, nil)
}

// filterDatastoreError returns err, unless it's just about datastore
// not being able to load an entity with old legacy struct fields into
// the Commit type that has since removed those fields.
func filterDatastoreError(err error) error {
	return filterAppEngineError(err, func(err error) bool {
		if em, ok := err.(*datastore.ErrFieldMismatch); ok {
			switch em.FieldName {
			case "NeedsBenchmarking", "TryPatch", "FailNotificationSent":
				// Removed in CLs 208397 and 208324.
				return true
			case "PackagePath", "ParentHash", "Num", "User", "Desc", "Time", "Branch", "NextNum", "Kind":
				// Removed in move to maintner in CL 208697.
				return true
			}
		}
		return false
	})
}

// filterNoSuchEntity returns err, unless it's just about datastore
// not being able to load an entity because it doesn't exist.
func filterNoSuchEntity(err error) error {
	return filterAppEngineError(err, func(err error) bool {
		return err == datastore.ErrNoSuchEntity
	})
}

// filterAppEngineError returns err, unless ignore(err) is true,
// in which case it returns nil. If err is an datastore.MultiError,
// it returns either nil (if all errors are ignored) or a deep copy
// with the non-ignored errors.
func filterAppEngineError(err error, ignore func(error) bool) error {
	if err == nil || ignore(err) {
		return nil
	}
	if me, ok := err.(datastore.MultiError); ok {
		me2 := make(datastore.MultiError, 0, len(me))
		for _, err := range me {
			if e2 := filterAppEngineError(err, ignore); e2 != nil {
				me2 = append(me2, e2)
			}
		}
		if len(me2) == 0 {
			return nil
		}
		return me2
	}
	return err
}

// getOrMakePackageInTx fetches a Package by path from the datastore,
// creating it if necessary.
func getOrMakePackageInTx(ctx context.Context, tx *datastore.Transaction, path string) (*Package, error) {
	p := &Package{Path: path}
	if path != "" {
		p.Name = pathpkg.Base(path)
	} else {
		p.Name = "Go"
	}
	err := tx.Get(p.Key(), p)
	err = filterDatastoreError(err)
	if err == datastore.ErrNoSuchEntity {
		if _, err := tx.Put(p.Key(), p); err != nil {
			return nil, err
		}
		return p, nil
	}
	if err != nil {
		return nil, err
	}
	return p, nil
}

type builderAndGoHash struct {
	builder, goHash string
}

// A Commit describes an individual commit in a package.
//
// Each Commit entity is a descendant of its associated Package entity.
// In other words, all Commits with the same PackagePath belong to the same
// datastore entity group.
type Commit struct {
	PackagePath string // (empty for main repo commits)
	Hash        string

	// ResultData is the Data string of each build Result for this Commit.
	// For non-Go commits, only the Results for the current Go tip, weekly,
	// and release Tags are stored here. This is purely de-normalized data.
	// The complete data set is stored in Result entities.
	//
	// Each string is formatted as builder|OK|LogHash|GoHash.
	ResultData []string `datastore:",noindex"`
}

func (com *Commit) Key() *datastore.Key {
	if com.Hash == "" {
		panic("tried Key on Commit with empty Hash")
	}
	p := Package{Path: com.PackagePath}
	key := com.PackagePath + "|" + com.Hash
	return dsKey("Commit", key, p.Key())
}

// Valid reports whether the commit is valid.
func (c *Commit) Valid() bool {
	// Valid really just means the hash is populated.
	return validHash(c.Hash)
}

// each result line is approx 105 bytes. This constant is a tradeoff between
// build history and the AppEngine datastore limit of 1mb.
const maxResults = 1000

// AddResult adds the denormalized Result data to the Commit's
// ResultData field.
func (com *Commit) AddResult(tx *datastore.Transaction, r *Result) error {
	err := tx.Get(com.Key(), com)
	if err == datastore.ErrNoSuchEntity {
		// If it doesn't exist, we create it below.
	} else {
		err = filterDatastoreError(err)
		if err != nil {
			return fmt.Errorf("Commit.AddResult, getting Commit: %v", err)
		}
	}

	var resultExists bool
	for i, s := range com.ResultData {
		// if there already exists result data for this builder at com, overwrite it.
		if strings.HasPrefix(s, r.Builder+"|") && strings.HasSuffix(s, "|"+r.GoHash) {
			resultExists = true
			com.ResultData[i] = r.Data()
		}
	}
	if !resultExists {
		// otherwise, add the new result data for this builder.
		com.ResultData = trim(append(com.ResultData, r.Data()), maxResults)
	}
	if !com.Valid() {
		return errors.New("putting Commit: commit is not valid")
	}
	if _, err := tx.Put(com.Key(), com); err != nil {
		return fmt.Errorf("putting Commit: %v", err)
	}
	return nil
}

// RemoveResult removes the denormalized Result data from the ResultData field
// for the given builder and go hash.
// It must be called from within the datastore transaction that gets and puts
// the Commit. Note this is slightly different to AddResult, above.
func (com *Commit) RemoveResult(r *Result) {
	var rd []string
	for _, s := range com.ResultData {
		if strings.HasPrefix(s, r.Builder+"|") && strings.HasSuffix(s, "|"+r.GoHash) {
			continue
		}
		rd = append(rd, s)
	}
	com.ResultData = rd
}

func trim(s []string, n int) []string {
	l := min(len(s), n)
	return s[len(s)-l:]
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// Result returns the build Result for this Commit for the given builder/goHash.
//
// For the main Go repo, goHash is the empty string.
func (c *Commit) Result(builder, goHash string) *Result {
	r := result(c.ResultData, c.Hash, c.PackagePath, builder, goHash)
	if r == nil {
		return nil
	}
	return &r.Result
}

// Result returns the build Result for this commit for the given builder/goHash.
//
// For the main Go repo, goHash is the empty string.
func (c *CommitInfo) Result(builder, goHash string) *DisplayResult {
	if r := result(c.ResultData, c.Hash, c.PackagePath, builder, goHash); r != nil {
		return r
	}
	if u, ok := c.BuildingURLs[builderAndGoHash{builder, goHash}]; ok {
		return &DisplayResult{Result: Result{
			Builder:     builder,
			BuildingURL: u,
			Hash:        c.Hash,
			GoHash:      goHash,
		}}
	}
	if fakeResults {
		// Create a fake random result.
		switch rand.Intn(3) {
		default:
			return nil
		case 1:
			return &DisplayResult{Result: Result{
				Builder: builder,
				Hash:    c.Hash,
				GoHash:  goHash,
				OK:      true,
			}}
		case 2:
			return &DisplayResult{Result: Result{
				Builder: builder,
				Hash:    c.Hash,
				GoHash:  goHash,
				LogHash: "fakefailureurl",
			}}
		}
	}
	return nil
}

type DisplayResult struct {
	Result
	Noise bool
}

func (r *DisplayResult) LogURL() string {
	if strings.HasPrefix(r.LogHash, "https://") {
		return r.LogHash
	} else {
		return "/log/" + r.LogHash
	}
}

func result(resultData []string, hash, packagePath, builder, goHash string) *DisplayResult {
	for _, r := range resultData {
		if !strings.HasPrefix(r, builder) {
			// Avoid strings.SplitN alloc in the common case.
			continue
		}
		p := strings.SplitN(r, "|", 4)
		if len(p) != 4 || p[0] != builder || p[3] != goHash {
			continue
		}
		return partsToResult(hash, packagePath, p)
	}
	return nil
}

// isUntested reports whether a cell in the build.golang.org grid is
// an untested configuration.
//
// repo is "go", "net", etc.
// branch is the branch of repo "master" or "release-branch.go1.12"
// goBranch applies only if repo != "go" and is of form "master" or "release-branch.go1.N"
//
// As a special case, "tip" is an alias for "master", since this app
// still uses a bunch of hg terms from when we used hg.
func isUntested(builder, repo, branch, goBranch string) bool {
	if strings.HasSuffix(builder, "-🐇") {
		// LUCI builders are never considered untested.
		//
		// Note: It would be possible to improve this by reporting
		// whether a given LUCI builder exists for a given x/ repo.
		// That needs more bookkeeping and code, so left for later.
		return false
	}
	if branch == "tip" {
		branch = "master"
	}
	if goBranch == "tip" {
		goBranch = "master"
	}
	bc, ok := dashboard.Builders[builder]
	if !ok {
		// Unknown builder, so not tested.
		return true
	}
	return !bc.BuildsRepoPostSubmit(repo, branch, goBranch)
}

// knownIssue returns a known issue for the named builder,
// or zero if there isn't a known issue.
func knownIssue(builder string) int {
	bc, ok := dashboard.Builders[builder]
	if !ok {
		// Unknown builder.
		return 0
	}
	if len(bc.KnownIssues) > 0 {
		return bc.KnownIssues[0]
	}
	return 0
}

// Results returns the build results for this Commit.
func (c *CommitInfo) Results() (results []*DisplayResult) {
	for _, r := range c.ResultData {
		p := strings.SplitN(r, "|", 4)
		if len(p) != 4 {
			continue
		}
		results = append(results, partsToResult(c.Hash, c.PackagePath, p))
	}
	return
}

// ResultGoHashes, for non-go repos, returns the list of Go hashes that
// this repo has been (or should be) built at.
//
// For the main Go repo it always returns a slice with 1 element: the
// empty string.
func (c *CommitInfo) ResultGoHashes() []string {
	// For the main repo, just return the empty string
	// (there's no corresponding main repo hash for a main repo Commit).
	// This function is only really useful for sub-repos.
	if c.PackagePath == "" {
		return []string{""}
	}
	var hashes []string
	for _, r := range c.ResultData {
		p := strings.SplitN(r, "|", 4)
		if len(p) != 4 {
			continue
		}
		// Append only new results (use linear scan to preserve order).
		if !contains(hashes, p[3]) {
			hashes = append(hashes, p[3])
		}
	}
	// Return results in reverse order (newest first).
	reverse(hashes)
	return hashes
}

func contains(t []string, s string) bool {
	for _, s2 := range t {
		if s2 == s {
			return true
		}
	}
	return false
}

func reverse(s []string) {
	for i := 0; i < len(s)/2; i++ {
		j := len(s) - i - 1
		s[i], s[j] = s[j], s[i]
	}
}

// partsToResult creates a DisplayResult from ResultData substrings.
func partsToResult(hash, packagePath string, p []string) *DisplayResult {
	return &DisplayResult{
		Result: Result{
			Builder:     p[0],
			Hash:        hash,
			PackagePath: packagePath,
			GoHash:      p[3],
			OK:          p[1] == "true",
			LogHash:     p[2],
		},
		Noise: p[1] == "infra_failure",
	}
}

// A Result describes a build result for a Commit on an OS/architecture.
//
// Each Result entity is a descendant of its associated Package entity.
type Result struct {
	Builder     string // "os-arch[-note]"
	PackagePath string // (empty for Go commits, else "golang.org/x/foo")
	Hash        string

	// The Go Commit this was built against (when PackagePath != ""; empty for Go commits).
	GoHash string

	BuildingURL string `datastore:"-"` // non-empty if currently building
	OK          bool
	Log         string `datastore:"-"`        // for JSON unmarshaling only
	LogHash     string `datastore:",noindex"` // Key to the Log record.

	RunTime int64 // time to build+test in nanoseconds
}

func (r *Result) Key() *datastore.Key {
	p := Package{Path: r.PackagePath}
	key := r.Builder + "|" + r.PackagePath + "|" + r.Hash + "|" + r.GoHash
	return dsKey("Result", key, p.Key())
}

func (r *Result) Valid() error {
	if !validHash(r.Hash) {
		return errors.New("invalid Hash")
	}
	if r.PackagePath != "" && !validHash(r.GoHash) {
		return errors.New("invalid GoHash")
	}
	return nil
}

// Data returns the Result in string format
// to be stored in Commit's ResultData field.
func (r *Result) Data() string {
	return fmt.Sprintf("%v|%v|%v|%v", r.Builder, r.OK, r.LogHash, r.GoHash)
}

// A Log is a gzip-compressed log file stored under the SHA1 hash of the
// uncompressed log text.
type Log struct {
	CompressedLog []byte `datastore:",noindex"`
}

func (l *Log) Text() ([]byte, error) {
	d, err := gzip.NewReader(bytes.NewBuffer(l.CompressedLog))
	if err != nil {
		return nil, fmt.Errorf("reading log data: %v", err)
	}
	b, err := io.ReadAll(d)
	if err != nil {
		return nil, fmt.Errorf("reading log data: %v", err)
	}
	return b, nil
}

func (h handler) putLog(c context.Context, text string) (hash string, err error) {
	b := new(bytes.Buffer)
	z, _ := gzip.NewWriterLevel(b, gzip.BestCompression)
	io.WriteString(z, text)
	z.Close()
	hash = loghash.New(text)
	key := dsKey("Log", hash, nil)
	_, err = h.datastoreCl.Put(c, key, &Log{b.Bytes()})
	return
}
