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

// Package zip_sum_test tests that the module zip files produced by modfetch
// have consistent content sums. Ideally the zip files themselves are also
// stable over time, though this is not strictly necessary.
//
// This test loads a table from testdata/zip_sums.csv. The table has columns
// for module path, version, content sum, and zip file hash. The table
// includes a large number of real modules. The test downloads these modules
// in direct mode and verifies the zip files.
//
// This test is very slow, and it depends on outside modules that change
// frequently, so this is a manual test. To enable it, pass the -zipsum flag.
package zip_sum_test

import (
	"context"
	"crypto/sha256"
	"encoding/csv"
	"encoding/hex"
	"flag"
	"fmt"
	"internal/testenv"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"cmd/go/internal/cfg"
	"cmd/go/internal/modfetch"
	"cmd/go/internal/modload"

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

var (
	updateTestData = flag.Bool("u", false, "when set, tests may update files in testdata instead of failing")
	enableZipSum   = flag.Bool("zipsum", false, "enable TestZipSums")
	debugZipSum    = flag.Bool("testwork", false, "when set, TestZipSums will preserve its test directory")
	modCacheDir    = flag.String("zipsumcache", "", "module cache to use instead of temp directory")
	shardCount     = flag.Int("zipsumshardcount", 1, "number of shards to divide TestZipSums into")
	shardIndex     = flag.Int("zipsumshard", 0, "index of TestZipSums shard to test (0 <= zipsumshard < zipsumshardcount)")
)

const zipSumsPath = "testdata/zip_sums.csv"

type zipSumTest struct {
	m                     module.Version
	wantSum, wantFileHash string
}

func TestZipSums(t *testing.T) {
	if !*enableZipSum {
		// This test is very slow and heavily dependent on external repositories.
		// Only run it explicitly.
		t.Skip("TestZipSum not enabled with -zipsum")
	}
	if *shardCount < 1 {
		t.Fatal("-zipsumshardcount must be a positive integer")
	}
	if *shardIndex < 0 || *shardCount <= *shardIndex {
		t.Fatal("-zipsumshard must be between 0 and -zipsumshardcount")
	}

	testenv.MustHaveGoBuild(t)
	testenv.MustHaveExternalNetwork(t)
	testenv.MustHaveExecPath(t, "bzr")
	testenv.MustHaveExecPath(t, "git")
	// TODO(jayconrod): add hg, svn, and fossil modules to testdata.
	// Could not find any for now.

	tests, err := readZipSumTests()
	if err != nil {
		t.Fatal(err)
	}

	if *modCacheDir != "" {
		cfg.BuildContext.GOPATH = *modCacheDir
	} else {
		tmpDir, err := ioutil.TempDir("", "TestZipSums")
		if err != nil {
			t.Fatal(err)
		}
		if *debugZipSum {
			fmt.Fprintf(os.Stderr, "TestZipSums: modCacheDir: %s\n", tmpDir)
		} else {
			defer os.RemoveAll(tmpDir)
		}
		cfg.BuildContext.GOPATH = tmpDir
	}

	cfg.GOPROXY = "direct"
	cfg.GOSUMDB = "off"
	modload.Init()

	// Shard tests by downloading only every nth module when shard flags are set.
	// This makes it easier to test small groups of modules quickly. We avoid
	// testing similarly named modules together (the list is sorted by module
	// path and version).
	if *shardCount > 1 {
		r := *shardIndex
		w := 0
		for r < len(tests) {
			tests[w] = tests[r]
			w++
			r += *shardCount
		}
		tests = tests[:w]
	}

	// Download modules with a rate limit. We may run out of file descriptors
	// or cause timeouts without a limit.
	needUpdate := false
	for i := range tests {
		test := &tests[i]
		name := fmt.Sprintf("%s@%s", strings.ReplaceAll(test.m.Path, "/", "_"), test.m.Version)
		t.Run(name, func(t *testing.T) {
			t.Parallel()
			zipPath, err := modfetch.DownloadZip(context.Background(), test.m)
			if err != nil {
				if *updateTestData {
					t.Logf("%s: could not download module: %s (will remove from testdata)", test.m, err)
					test.m.Path = "" // mark for deletion
					needUpdate = true
				} else {
					t.Errorf("%s: could not download module: %s", test.m, err)
				}
				return
			}

			sum := modfetch.Sum(test.m)
			if sum != test.wantSum {
				if *updateTestData {
					t.Logf("%s: updating content sum to %s", test.m, sum)
					test.wantSum = sum
					needUpdate = true
				} else {
					t.Errorf("%s: got content sum %s; want sum %s", test.m, sum, test.wantSum)
					return
				}
			}

			h := sha256.New()
			f, err := os.Open(zipPath)
			if err != nil {
				t.Errorf("%s: %v", test.m, err)
			}
			defer f.Close()
			if _, err := io.Copy(h, f); err != nil {
				t.Errorf("%s: %v", test.m, err)
			}
			zipHash := hex.EncodeToString(h.Sum(nil))
			if zipHash != test.wantFileHash {
				if *updateTestData {
					t.Logf("%s: updating zip file hash to %s", test.m, zipHash)
					test.wantFileHash = zipHash
					needUpdate = true
				} else {
					t.Errorf("%s: got zip file hash %s; want hash %s (but content sum matches)", test.m, zipHash, test.wantFileHash)
				}
			}
		})
	}

	if needUpdate {
		// Remove tests marked for deletion
		r, w := 0, 0
		for r < len(tests) {
			if tests[r].m.Path != "" {
				tests[w] = tests[r]
				w++
			}
			r++
		}
		tests = tests[:w]

		if err := writeZipSumTests(tests); err != nil {
			t.Error(err)
		}
	}
}

func readZipSumTests() ([]zipSumTest, error) {
	f, err := os.Open(filepath.FromSlash(zipSumsPath))
	if err != nil {
		return nil, err
	}
	defer f.Close()
	r := csv.NewReader(f)

	var tests []zipSumTest
	for {
		line, err := r.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			return nil, err
		} else if len(line) != 4 {
			return nil, fmt.Errorf("%s:%d: malformed line", f.Name(), len(tests)+1)
		}
		test := zipSumTest{m: module.Version{Path: line[0], Version: line[1]}, wantSum: line[2], wantFileHash: line[3]}
		tests = append(tests, test)
	}
	return tests, nil
}

func writeZipSumTests(tests []zipSumTest) (err error) {
	f, err := os.Create(filepath.FromSlash(zipSumsPath))
	if err != nil {
		return err
	}
	defer func() {
		if cerr := f.Close(); err == nil && cerr != nil {
			err = cerr
		}
	}()
	w := csv.NewWriter(f)
	line := make([]string, 0, 4)
	for _, test := range tests {
		line = append(line[:0], test.m.Path, test.m.Version, test.wantSum, test.wantFileHash)
		if err := w.Write(line); err != nil {
			return err
		}
	}
	w.Flush()
	return nil
}
