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

// Gosumcheck checks a go.sum file against a go.sum database server.
//
// Usage:
//
//	gosumcheck [-h H] [-k key] [-u url] [-v] go.sum
//
// The -h flag changes the tile height (default 8).
//
// The -k flag changes the go.sum database server key.
//
// The -u flag overrides the URL of the server (usually set from the key name).
//
// The -v flag enables verbose output.
// In particular, it causes gosumcheck to report
// the URL and elapsed time for each server request.
//
// WARNING! WARNING! WARNING!
//
// Gosumcheck is meant as a proof of concept demo and should not be
// used in production scripts or continuous integration testing.
// It does not cache any downloaded information from run to run,
// making it expensive and also keeping it from detecting server
// misbehavior or successful HTTPS man-in-the-middle timeline forks.
//
// To discourage misuse in automated settings, gosumcheck does not
// set any exit status to report whether any problems were found.
//
package main

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"

	"golang.org/x/mod/sumdb"
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: gosumcheck [-h H] [-k key] [-u url] [-v] go.sum...\n")
	os.Exit(2)
}

var (
	height = flag.Int("h", 8, "tile height")
	vkey   = flag.String("k", "sum.golang.org+033de0ae+Ac4zctda0e5eza+HJyk9SxEdh+s3Ux18htTTAD8OuAn8", "key")
	url    = flag.String("u", "", "url to server (overriding name)")
	vflag  = flag.Bool("v", false, "enable verbose output")
)

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

	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		usage()
	}

	client := sumdb.NewClient(new(clientOps))

	// Look in environment explicitly, so that if 'go env' is old and
	// doesn't know about GONOSUMDB, we at least get anything
	// set in the environment.
	env := os.Getenv("GONOSUMDB")
	if env == "" {
		out, err := exec.Command("go", "env", "GONOSUMDB").CombinedOutput()
		if err != nil {
			log.Fatalf("go env GONOSUMDB: %v\n%s", err, out)
		}
		env = strings.TrimSpace(string(out))
	}
	client.SetGONOSUMDB(env)

	for _, arg := range flag.Args() {
		data, err := ioutil.ReadFile(arg)
		if err != nil {
			log.Fatal(err)
		}
		checkGoSum(client, arg, data)
	}
}

func checkGoSum(client *sumdb.Client, name string, data []byte) {
	lines := strings.Split(string(data), "\n")
	if lines[len(lines)-1] != "" {
		log.Printf("error: final line missing newline")
		return
	}
	lines = lines[:len(lines)-1]

	errs := make([]string, len(lines))
	var wg sync.WaitGroup
	for i, line := range lines {
		wg.Add(1)
		go func(i int, line string) {
			defer wg.Done()
			f := strings.Fields(line)
			if len(f) != 3 {
				errs[i] = "invalid number of fields"
				return
			}

			dbLines, err := client.Lookup(f[0], f[1])
			if err != nil {
				if err == sumdb.ErrGONOSUMDB {
					errs[i] = fmt.Sprintf("%s@%s: %v", f[0], f[1], err)
				} else {
					// Otherwise Lookup properly adds the prefix itself.
					errs[i] = err.Error()
				}
				return
			}
			hashAlgPrefix := f[0] + " " + f[1] + " " + f[2][:strings.Index(f[2], ":")+1]
			for _, dbLine := range dbLines {
				if dbLine == line {
					return
				}
				if strings.HasPrefix(dbLine, hashAlgPrefix) {
					errs[i] = fmt.Sprintf("%s@%s hash mismatch: have %s, want %s", f[0], f[1], line, dbLine)
					return
				}
			}
			errs[i] = fmt.Sprintf("%s@%s hash algorithm mismatch: have %s, want one of:\n\t%s", f[0], f[1], line, strings.Join(dbLines, "\n\t"))
		}(i, line)
	}
	wg.Wait()

	for i, err := range errs {
		if err != "" {
			fmt.Printf("%s:%d: %s\n", name, i+1, err)
		}
	}
}

type clientOps struct{}

func (*clientOps) ReadConfig(file string) ([]byte, error) {
	if file == "key" {
		return []byte(*vkey), nil
	}
	if strings.HasSuffix(file, "/latest") {
		// Looking for cached latest tree head.
		// Empty result means empty tree.
		return []byte{}, nil
	}
	return nil, fmt.Errorf("unknown config %s", file)
}

func (*clientOps) WriteConfig(file string, old, new []byte) error {
	// Ignore writes.
	return nil
}

func (*clientOps) ReadCache(file string) ([]byte, error) {
	return nil, fmt.Errorf("no cache")
}

func (*clientOps) WriteCache(file string, data []byte) {
	// Ignore writes.
}

func (*clientOps) Log(msg string) {
	log.Print(msg)
}

func (*clientOps) SecurityError(msg string) {
	log.Fatal(msg)
}

func init() {
	http.DefaultClient.Timeout = 1 * time.Minute
}

func (*clientOps) ReadRemote(path string) ([]byte, error) {
	name := *vkey
	if i := strings.Index(name, "+"); i >= 0 {
		name = name[:i]
	}
	start := time.Now()
	target := "https://" + name + path
	if *url != "" {
		target = *url + path
	}
	resp, err := http.Get(target)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("GET %v: %v", target, resp.Status)
	}
	data, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
	if err != nil {
		return nil, err
	}
	if *vflag {
		fmt.Fprintf(os.Stderr, "%.3fs %s\n", time.Since(start).Seconds(), target)
	}
	return data, nil
}
