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

//go:build ignore
// +build ignore

// This program generates zip_signatures.gen.go.

// The program depends on its own generated file. To regenerate from scratch,
// manually edit the generated file, leaving an empty map literal.

package main

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"log"
	"sort"
	"strings"
	"text/template"
	"time"

	"golang.org/x/mod/semver"
	"golang.org/x/pkgsite/internal/fetch"
	"golang.org/x/pkgsite/internal/proxy"
)

var (
	verbose = flag.Bool("v", false, "verbose output")
	check   = flag.Bool("check", false, "check signatures of module@version command-line args")
)

// The list of modules whose exact forks will be excluded from processing. The
// second field is the highest (in the semver sense) without a go.mod file;
// versions with go.mod files are handled by the alternative-module logic.
var largeNoMods = []struct {
	modulePath          string
	highestNoModVersion string
}{
	{"github.com/aws/aws-sdk-go", "v1.14.30"},
	{"github.com/kubernetes/kubernetes", "v1.15.0-alpha.0"},
	{"github.com/Azure/azure-sdk-for-go", "v54.3.0"},
	{"github.com/ethereum/go-ethereum", "v1.9.7"},
	{"github.com/moby/moby", "v20.10.6"},
	{"github.com/influxdata/influxdb", "v1.7.9-dev1"},
	{"github.com/etcd-io/etcd", "v3.3.25"},
}

const goFile = "zip_signatures.gen.go"

type sig struct {
	Modver    fetch.Modver
	Signature string
}

func main() {
	flag.Parse()
	ctx := context.Background()

	prox, err := proxy.New("https://proxy.golang.org")
	if err != nil {
		log.Fatal(err)
	}

	if *check {
		err = checkSignatures(ctx, prox, flag.Args())
	} else {
		err = generateSignatures(ctx, prox)
	}
	if err != nil {
		log.Fatal(err)
	}
}

func generateSignatures(ctx context.Context, prox *proxy.Client) error {
	// Remember all the modvers we've already computed, to avoid doing so again.
	seen := map[fetch.Modver]bool{}
	for _, mvs := range fetch.ZipSignatures {
		for _, mv := range mvs {
			seen[mv] = true
		}
	}

	for _, m := range largeNoMods {
		// Get all tagged versions of the module.
		versions, err := prox.Versions(ctx, m.modulePath)
		if err != nil {
			return err
		}
		// Keep versions that are less than or equal to the highest version without a go.mod file.
		var noGoModVersions []string
		for _, v := range versions {
			if semver.Compare(v, m.highestNoModVersion) <= 0 {
				noGoModVersions = append(noGoModVersions, v)
			}
		}
		// Compute the signature for each of those versions.
		for _, v := range noGoModVersions {
			modver := fetch.Modver{ModulePath: m.modulePath, Version: v}
			if seen[modver] {
				if *verbose {
					fmt.Printf("%-40s already computed\n", modver)
				}
				continue
			}
			s, err := computeSignature(ctx, prox, modver)
			if err != nil {
				log.Printf("skipping %s: %v", modver, err)
			} else {
				fetch.ZipSignatures[s] = append(fetch.ZipSignatures[s], modver)
			}
		}
	}
	return writeGoFile(goFile)
}

func checkSignatures(ctx context.Context, prox *proxy.Client, args []string) error {
	for _, arg := range args {
		words := strings.Split(arg, "@")
		if len(words) != 2 {
			return fmt.Errorf("invalid module@version: %q", arg)
		}
		sig, err := computeSignature(ctx, prox, fetch.Modver{ModulePath: words[0], Version: words[1]})
		if err != nil {
			return err
		}
		matches := fetch.ZipSignatures[sig]
		fmt.Printf("%s: signature %s matches %v\n", arg, sig, matches)
	}
	return nil
}

func computeSignature(ctx context.Context, prox *proxy.Client, mv fetch.Modver) (string, error) {
	start := time.Now()
	zr, err := prox.Zip(ctx, mv.ModulePath, mv.Version)
	if err != nil {
		return "", err
	}
	sig, err := fetch.ZipSignature(zr, mv.String())
	if err != nil {
		return "", err
	}
	dur := time.Since(start)
	if *verbose {
		fmt.Printf("%-40s %s    %.1fs\n", mv, sig, dur.Seconds())
	}
	return sig, nil
}

// writeGoFile writes ZipSignatures back to the generated file.
func writeGoFile(filename string) error {
	// Convert the ZipSignatures map to a slice of key-value pairs.
	type kv struct {
		Signature string
		Modvers   []fetch.Modver
		key       string
	}

	var kvs []kv
	for sig, mvs := range fetch.ZipSignatures {
		kvs = append(kvs, kv{sig, mvs, mvs[0].String()})
	}
	// Sort the slice so that the diffs will show only the changes. Otherwise
	// random map iteration order will result in messy diffs even if no
	// signatures were added.
	sort.Slice(kvs, func(i, j int) bool { return kvs[i].key < kvs[j].key })

	// Execute the template.
	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, kvs); err != nil {
		return err
	}
	// Run gofmt.
	src, err := format.Source(buf.Bytes())
	if err != nil {
		return err
	}
	return ioutil.WriteFile(filename, src, 0644)
}

// Template for the generated source file.
// The map value is a []Modver because it's possible for two modules to have the same contents.
// For example, github.com/aws/aws-sdk-go v1.9.0 and v1.9.44 (perhaps due to a bad tag?).
var tmpl = template.Must(template.New("").Parse(`
// Copyright 2021 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.

// Code generated by gen_zip_signatures.go; DO NOT EDIT.

package fetch

var ZipSignatures = map[string][]Modver{
{{range .}}
    "{{.Signature}}": []Modver{
	{{range .Modvers -}}
		{"{{.ModulePath}}", "{{.Version}}"},
	{{- end}}
	},
{{- end}}
}
`))
