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

// Fetchlogs downloads build failure logs from the Go dashboard so
// they can be accessed and searched from the local file system.
//
// It organizes these logs into two directories created in the
// directory specified by the -dir flag (which typically defaults to
// ~/.cache/fetchlogs). The log/ directory contains all log files
// named the same way they are named by the dashboard (which happens
// to be the SHA-1 of their contents). The rev/ directory contains
// symlinks back to these logs named
//
//	rev/<ISO 8601 commit date>-<git revision>/<builder>
//
// Fetchlogs will reuse existing log files and revision symlinks, so
// it only has to download logs that are new since the last time it
// was run.
//
// This makes failures easily searchable with standard tools. For
// example, to list the revisions and builders with a particular
// failure, use:
//
//	grep -lR <regexp> rev | sort
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"sync"
	"time"

	"golang.org/x/build/maintner"
	"golang.org/x/build/maintner/godata"
	"golang.org/x/build/repos"
	"golang.org/x/build/types"
)

var defaultDir = filepath.Join(xdgCacheDir(), "fetchlogs")

var (
	flagN         = flag.Int("n", 300, "limit to most recent `N` commits per repo")
	flagPar       = flag.Int("j", 5, "number of concurrent download `jobs`")
	flagDir       = flag.String("dir", defaultDir, "`directory` to save logs to")
	flagRepo      = flag.String("repo", "go", `comma-separated list of repos to fetch logs for, or "all" for all known repos`)
	flagBranch    = flag.String("branch", "", `comma-separated list of Go repo branches to fetch logs for; default branch if empty`)
	flagDashboard = flag.String("dashboard", "https://build.golang.org", `the dashboard root url`)
)

func main() {
	log.SetPrefix("fetchlogs: ")
	log.SetFlags(0)

	flag.Parse()
	if flag.NArg() != 0 {
		flag.Usage()
		os.Exit(2)
	}

	// If the top-level directory is the default XDG cache
	// directory, make sure it exists.
	if *flagDir == defaultDir {
		if err := xdgCreateDir(*flagDir); err != nil {
			log.Fatal(err)
		}
	}

	// Create directory structure.
	if err := os.Chdir(*flagDir); err != nil {
		log.Fatal(err)
	}
	ensureDir("log")
	ensureDir("rev")

	// Set up fetchers.
	fetcher := newFetcher(*flagPar)
	wg := sync.WaitGroup{}

	// Fetch dashboard pages.
	for _, repo := range parseRepoFlag() {
		for branch := range strings.SplitSeq(*flagBranch, ",") {
			project := repo.GoGerritProject
			haveCommits := 0
			for page := 0; haveCommits < *flagN; page++ {
				dashURL := fmt.Sprintf("%s/?mode=json&page=%d", *flagDashboard, page)
				if project != "go" {
					dashURL += "&repo=" + url.QueryEscape(repo.ImportPath)
				}
				if branch != "" {
					dashURL += "&branch=" + url.QueryEscape(branch)
				}
				index, err := fetcher.get(dashURL)
				if err != nil {
					log.Fatal(err)
				}

				var status types.BuildStatus
				if err = json.NewDecoder(index).Decode(&status); err != nil {
					log.Fatal("error unmarshalling result: ", err)
				}
				index.Close()

				if len(status.Revisions) == 0 {
					// We asked for a page of revisions and received a valid reply with none.
					// Assume that there are no more beyond this.
					break
				}

				for _, rev := range status.Revisions {
					if haveCommits >= *flagN {
						break
					}
					if rev.Repo != project {
						// The results for the "go" repo (fetched without the "&repo" query
						// parameter) empirically include some subrepo results for release
						// branches.
						//
						// Those aren't really relevant to the "go" repo — and they should be
						// included when we fetch the subrepo explicitly anyway — so filter
						// them out here.
						continue
					}
					haveCommits++

					// Create a revision directory. This way we
					// have a record of commits with no failures.
					date, err := parseRevDate(rev.Date)
					if err != nil {
						log.Fatal("malformed revision date: ", err)
					}
					var goDate time.Time
					if rev.GoRevision != "" {
						commit, err := goProject(useCached).GitCommit(rev.GoRevision)
						if err != nil {
							// A rare race is possible here: if a commit is added to the Go repo
							// after the initial maintner load, and a dashboard test run completes
							// for that commit before we're done fetching logs, the maintner data
							// might not include that commit. To rule out that possibility, refresh
							// the local maintner data before bailing out.
							commit, err = goProject(forceRefresh).GitCommit(rev.GoRevision)
							if err != nil {
								log.Fatal("invalid GoRevision: ", err)
							}
						}
						goDate = commit.CommitTime
					}
					revDir, revDirDepth := revToDir(rev.Revision, date, rev.GoRevision, goDate)
					ensureDir(revDir)

					if rev.GoRevision != "" {
						// In October 2021 we started creating a separate subdirectory for
						// each Go repo commit. (Previously, we overwrote the link for each
						// subrepo commit when downloading a new Go commit.) Remove the
						// previous links, if any, so that greplogs won't double-count them.
						prevRevDir, _ := revToDir(rev.Revision, date, "", time.Time{})
						if err := os.RemoveAll(prevRevDir); err != nil {
							log.Fatal(err)
						}
					}

					// Save revision metadata.
					buf := bytes.Buffer{}
					enc := json.NewEncoder(&buf)
					if err = enc.Encode(rev); err != nil {
						log.Fatal(err)
					}
					if err = writeFileAtomic(filepath.Join(revDir, ".rev.json"), &buf); err != nil {
						log.Fatal("error saving revision metadata: ", err)
					}

					// Save builders list so Results list can be
					// interpreted.
					if err = enc.Encode(status.Builders); err != nil {
						log.Fatal(err)
					}
					if err = writeFileAtomic(filepath.Join(revDir, ".builders.json"), &buf); err != nil {
						log.Fatal("error saving builders metadata: ", err)
					}

					// Fetch revision logs.
					for i, res := range rev.Results {
						if res == "" || res == "ok" {
							continue
						}

						wg.Add(1)
						go func(builder, logURL string) {
							defer wg.Done()
							logPath := filepath.Join("log", filepath.Base(logURL))
							err := fetcher.getFile(logURL, logPath)
							if err != nil {
								log.Fatal("error fetching log: ", err)
							}
							if err := linkLog(revDir, revDirDepth, builder, logPath); err != nil {
								log.Fatal("error linking log: ", err)
							}
						}(status.Builders[i], res)
					}
				}
			}
		}
	}

	wg.Wait()
}

func parseRepoFlag() (rs []*repos.Repo) {
	if *flagRepo == "all" {
		for p, repo := range repos.ByGerritProject {
			if p == "go" || repo.ShowOnDashboard() {
				rs = append(rs, repo)
			}
		}
	} else {
		for p := range strings.SplitSeq(*flagRepo, ",") {
			p = strings.TrimSpace(p)
			repo := repos.ByGerritProject[p]
			if repo == nil {
				log.Fatalf("unknown repo %s", *flagRepo)
			}
			rs = append(rs, repo)
		}
	}
	sort.Slice(rs, func(i, j int) bool {
		pi := rs[i].GoGerritProject
		pj := rs[j].GoGerritProject

		// Read "go" first because it doesn't require maintner data.
		if pj == "go" {
			return false // Nothing is before "go".
		} else if pi == "go" {
			return true // "go" is before everything else.
		}

		return pi < pj
	})

	if len(rs) == 0 {
		log.Fatal("-repo flag does not contain any repos")
	}
	if rs[0].GoGerritProject == "go" && len(rs) > 1 {
		go func() {
			// Prefetch maintner data, since we'll likely need it and can hide
			// some of the latency behind processing the "go" project
			// (which does not need it).
			//
			// If the first repo is not "go", then we'll either need the maintner data
			// right away (in which case we can't hide any substantial latency) or not
			// at all (in which case we shouldn't bother churning memory and disk
			// pages to load it).
			_ = goProject(useCached)
		}()
	}

	return rs
}

// A fetcher downloads files over HTTP concurrently. It allows
// limiting the number of concurrent downloads and correctly handles
// multiple (possibly concurrent) fetches from the same URL to the
// same file.
type fetcher struct {
	tokens chan struct{}

	pending struct {
		sync.Mutex
		m map[string]*pendingFetch
	}
}

type pendingFetch struct {
	wchan chan struct{} // closed when fetch completes

	// err is the error, if any, that occurred during this fetch.
	// It will be set before wchan is closed.
	err error
}

func newFetcher(jobs int) *fetcher {
	f := new(fetcher)

	f.tokens = make(chan struct{}, *flagPar)
	for range jobs {
		f.tokens <- struct{}{}
	}

	f.pending.m = make(map[string]*pendingFetch)

	return f
}

// get performs an HTTP GET for URL and returns the body, while
// obeying the job limit on fetcher.
func (f *fetcher) get(url string) (io.ReadCloser, error) {
	<-f.tokens
	fmt.Println("fetching", url)
	resp, err := http.Get(url)
	f.tokens <- struct{}{}
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("GET %s: %v %s", url, resp.StatusCode, http.StatusText(resp.StatusCode))
	}

	return resp.Body, nil
}

// getFile performs an HTTP GET for URL and writes it to filename. If
// the destination file already exists, this returns immediately. If
// another goroutine is currently fetching filename, this blocks until
// the fetch is done and then returns.
func (f *fetcher) getFile(url string, filename string) error {
	// Do we already have it?
	if _, err := os.Stat(filename); err == nil {
		return nil
	} else if !os.IsNotExist(err) {
		return err
	}

	// Check if another fetcher is working on it.
	f.pending.Lock()
	if p, ok := f.pending.m[filename]; ok {
		f.pending.Unlock()
		<-p.wchan
		return p.err
	}

	p := &pendingFetch{wchan: make(chan struct{})}
	f.pending.m[filename] = p
	f.pending.Unlock()

	r, err := f.get(url)
	if err == nil {
		err = writeFileAtomic(filename, r)
		r.Close()
	}
	p.err = err

	close(p.wchan)
	return p.err
}

var (
	goProjectMu     sync.Mutex
	cachedGoProject *maintner.GerritProject
	goProjectErr    error
)

func getGoProject(ctx context.Context) (*maintner.GerritProject, error) {
	corpus, err := godata.Get(ctx)
	if err != nil {
		return nil, err
	}

	gp := corpus.Gerrit().Project("go.googlesource.com", "go")
	if gp == nil {
		return nil, fmt.Errorf("go.googlesource.com/go Gerrit project not found")
	}

	return gp, nil
}

func goProject(policy refreshPolicy) *maintner.GerritProject {
	goProjectMu.Lock()
	defer goProjectMu.Unlock()
	if policy == forceRefresh || (cachedGoProject == nil && goProjectErr == nil) {
		cachedGoProject, goProjectErr = getGoProject(context.Background())
	}

	if goProjectErr != nil {
		log.Fatal(goProjectErr)
	}
	return cachedGoProject
}

type refreshPolicy int8

const (
	useCached refreshPolicy = iota
	forceRefresh
)

// ensureDir creates directory name if it does not exist.
func ensureDir(name string) {
	err := os.MkdirAll(name, 0777)
	if err != nil {
		log.Fatal("error creating directory ", name, ": ", err)
	}
}

// writeFileAtomic atomically creates a file called filename and
// copies the data from r to the file.
func writeFileAtomic(filename string, r io.Reader) error {
	tmpPath := filename + ".tmp"
	if f, err := os.Create(tmpPath); err != nil {
		return err
	} else {
		_, err := io.Copy(f, r)
		if err == nil {
			err = f.Sync()
		}
		err2 := f.Close()
		if err == nil {
			err = err2
		}
		if err != nil {
			os.Remove(tmpPath)
			return err
		}
	}
	if err := os.Rename(tmpPath, filename); err != nil {
		os.Remove(tmpPath)
		return err
	}
	return nil
}

// linkLog creates a symlink for finding logPath based on its git
// revision and builder.
func linkLog(revDir string, revDirDepth int, builder, logPath string) error {
	// Create symlink.
	err := os.Symlink(strings.Repeat("../", revDirDepth)+logPath, filepath.Join(revDir, builder))
	if err != nil && !os.IsExist(err) {
		return err
	}

	return nil
}

// parseRevDate parses a revision date in RFC3339.
func parseRevDate(date string) (time.Time, error) {
	return time.Parse(time.RFC3339, date)
}

// revToDir returns the path of the revision directory for revision.
func revToDir(revision string, date time.Time, goRev string, goDate time.Time) (dir string, depth int) {
	if goDate.After(date) {
		date = goDate
	}
	dateStr := date.Format("2006-01-02T15:04:05")

	parts := []string{dateStr, revision[:7]}
	if goRev != "" {
		parts = append(parts, goRev[:7])
	}

	return filepath.Join("rev", strings.Join(parts, "-")), 2
}
