// Copyright 2018 The Fuchsia 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 cipd

import (
	"bytes"
	"encoding/hex"
	"io/ioutil"
	"os"
	"path"
	"reflect"
	"sort"
	"strings"
	"testing"

	"go.fuchsia.dev/jiri/jiritest/xtest"
)

const (
	// Some random valid cipd version tags from infra/tools/cipd
	cipdVersionForTestA = "git_revision:00e2d8b49a4e7505d1c71f19d15c9e7c5b9245a5"
	cipdVersionForTestB = "git_revision:8fac632847b1ce0de3b57d16d0f2193625f4a4f0"
	// package path and versions for ACL tests
	cipdPkgPathA    = "gn/gn/${platform}"
	cipdPkgVersionA = "git_revision:bdb0fd02324b120cacde634a9235405061c8ea06"
	cipdPkgPathB    = "notexist/notexist"
	cipdPkgVersionB = "git_revision:bdb0fd02324b120cacde634a9235405061c8ea06"
)

var (
	// Digests generated by cipd selfupdate-roll ...
	digestMapA = map[string]string{
		"linux-amd64":  "df37ffc2588e345a31ca790d773b6136fedbd2efbf9a34cb735dd34b6891c16c",
		"linux-arm64":  "650f2a045f8587062a16299a650aa24ba5c5c0652585a2d9bd56594369d5f99e",
		"linux-armv6l": "61b657c860ddc39d3286ced073c843852b1dafc0222af0bdc22ad988b289d733",
		"mac-amd64":    "4d015791ed6f03f305cf6a5a673a447e5c47ff5fdb701f43f99fba9ca73e61f8",
	}
	digestMapB = map[string]string{
		"linux-amd64":  "bdc971fd2895c3771e0709d2a3ec5fcace69c59a3a9f9dc33ab76fbc2f777d40",
		"linux-arm64":  "e1d6aadc9bfc155e9088aa3de39b9d3311c7359f398f372b5ad1c308e25edfeb",
		"linux-armv6l": "3ad97b47ecc1b358c8ebd1b0307087d354433d88f24bf8ece096fb05452837f9",
		"mac-amd64":    "167edadf7c7c019a40b9f7869a4c05b2d9834427dad68e295442ef9ebce88dba",
	}
	instanceIDMap = map[string]string{
		"gn/gn/linux-amd64": "0uGjKAZkJXPZjtYktgEwHiNbwsut_qRsk7ZCGGxi82IC",
		"gn/gn/mac-amd64":   "rN2F641yR4Bj-H1q8OwC_RiqRpUYxy3hryzRfPER9wcC",
	}
)

// TestFetchBinary tests fetchiBinary method by fetching a set of
// cipd binaries. This test requires network access
func TestFetchBinary(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	tmpDir, err := ioutil.TempDir("", "jiri-test")
	if err != nil {
		t.Error("failed to create temp dir for testing")
	}
	defer os.RemoveAll(tmpDir)

	tests := []struct {
		version string
		digest  map[string]string
	}{
		{cipdVersionForTestA, digestMapA},
		{cipdVersionForTestB, digestMapB},
	}

	for i, test := range tests {
		for platform, digest := range test.digest {
			cipdPath := path.Join(tmpDir, "cipd"+platform+test.version)
			if err := fetchBinary(fakex, cipdPath, platform, test.version, digest); err != nil {
				t.Errorf("test %d failed while retrieving cipd binary for platform %q on version %q with digest %q: %v", i, platform, test.version, digest, err)
			}
		}
	}
}

func TestCipdVersion(t *testing.T) {
	t.Parallel()
	// Assume cipd version is always a git commit hash for now
	versionStr := string(cipdVersion)
	if len(versionStr) != len("git_revision:00e2d8b49a4e7505d1c71f19d15c9e7c5b9245a5") ||
		!strings.HasPrefix(versionStr, "git_revision:") {
		t.Errorf("unsupported cipd version tag: %q", versionStr)
	}
	versionHash := versionStr[len("git_revision:"):]
	if _, err := hex.DecodeString(versionHash); err != nil {
		t.Errorf("unsupported cipd version tag: %q", versionStr)
	}
}

func TestFetchDigest(t *testing.T) {
	t.Parallel()
	tests := []string{
		"linux-amd64",
		"linux-arm64",
		"linux-armv6l",
		"mac-amd64",
	}

	for _, platform := range tests {
		digest, _, err := fetchDigest(platform)
		if err != nil {
			t.Errorf("failed to retrieve cipd digest for platform %q due to error: %v", platform, err)
		}
		if _, err := hex.DecodeString(digest); err != nil {
			t.Errorf("digest %q is not a valid hex string for platform %q", digest, platform)
		}
	}
}

func TestSelfUpdate(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	tmpDir, err := ioutil.TempDir("", "jiri-test")
	if err != nil {
		t.Error("failed to create temp dir for testing")
	}
	defer os.RemoveAll(tmpDir)
	// Bootstrap cipd to version A
	cipdPath := path.Join(tmpDir, "cipd")
	if err := fetchBinary(fakex, cipdPath, CipdPlatform.String(), cipdVersionForTestA, digestMapA[CipdPlatform.String()]); err != nil {
		t.Errorf("failed to bootstrap cipd with version %q: %v", cipdVersionForTestA, err)
	}
	// Perform cipd self update to version B
	if err := selfUpdate(cipdPath, cipdVersionForTestB); err != nil {
		t.Errorf("failed to perform cipd self update: %v", err)
	}
	// Verify self updated cipd
	cipdData, err := ioutil.ReadFile(cipdPath)
	if err != nil {
		t.Errorf("failed to read self-updated cipd binary: %v", err)
	}
	verified, err := verifyDigest(cipdData, digestMapB[CipdPlatform.String()])
	if err != nil {
		t.Errorf("digest failed verification for platform %q on version %q", CipdPlatform.String(), cipdVersionForTestB)
	}
	if !verified {
		t.Errorf("self-updated cipd failed integrity test")
	}
}

func TestBootsrap(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if cipdPath == "" {
		t.Errorf("bootstrap returned an empty path")
	}
	fileInfo, err := os.Stat(cipdPath)
	if err != nil {
		if os.IsNotExist(err) {
			t.Errorf("bootstrap failed, cipd binary was not found at %q", cipdPath)
		}
		t.Errorf("bootstrap failed, could not access cipd binary at %q due to error %v", cipdPath, err)
	}
	if fileInfo.Mode()&0111 == 0 {
		t.Errorf("bootstrap failed, cipd binary at %q is not executable", cipdBinary)
	}
}

func TestEnsure(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if err != nil {
		t.Errorf("bootstrap failed due to error: %v", err)
	}
	defer os.Remove(cipdPath)
	// Write test ensure file
	testEnsureFile, err := ioutil.TempFile("", "test_jiri*.ensure")
	if err != nil {
		t.Errorf("failed to create test ensure file: %v", err)
	}
	defer testEnsureFile.Close()
	defer os.Remove(testEnsureFile.Name())
	_, err = testEnsureFile.Write([]byte(`
$ParanoidMode CheckPresence

# GN
gn/gn/${platform} git_revision:bdb0fd02324b120cacde634a9235405061c8ea06
`))
	if err != nil {
		t.Errorf("failed to write test ensure file: %v", err)
	}
	testEnsureFile.Sync()
	tmpDir, err := ioutil.TempDir("", "jiri-test")
	if err != nil {
		t.Error("failed to creat temp dir for testing")
	}
	defer os.RemoveAll(tmpDir)
	// Invoke Ensure on test ensure file
	if err := Ensure(fakex, testEnsureFile.Name(), tmpDir, 30); err != nil {
		t.Errorf("ensure failed due to error: %v", err)
	}
	// Check the existence downloaded package
	gnPath := path.Join(tmpDir, "gn")
	if _, err := os.Stat(gnPath); err != nil {
		if os.IsNotExist(err) {
			t.Errorf("fetched cipd package is not found at %q", gnPath)
		}
		t.Errorf("failed to execute os.Stat() on fetched cipd package due to error: %v", err)
	}
}

func TestEnsureFileVerify(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if err != nil {
		t.Errorf("bootstrap failed due to error: %v", err)
	}
	defer os.Remove(cipdPath)
	// Write test ensure file
	testEnsureFile, err := ioutil.TempFile("", "test_jiri*.ensure")
	if err != nil {
		t.Errorf("failed to create test ensure file: %v", err)
	}
	defer testEnsureFile.Close()
	defer os.Remove(testEnsureFile.Name())
	_, err = testEnsureFile.Write([]byte(`
$ParanoidMode CheckPresence
$VerifiedPlatform linux-amd64
$VerifiedPlatform mac-amd64

# GN
gn/gn/${platform} git_revision:bdb0fd02324b120cacde634a9235405061c8ea06
`))
	if err != nil {
		t.Errorf("failed to write test ensure file: %v", err)
	}
	testEnsureFile.Sync()
	if err := EnsureFileVerify(fakex, testEnsureFile.Name()); err != nil {
		t.Error("ensure file failed verification")
	}
}

func TestEnsureFileVerifyInvalid(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if err != nil {
		t.Errorf("bootstrap failed due to error: %v", err)
	}
	defer os.Remove(cipdPath)
	// Write test ensure file
	testEnsureFile, err := ioutil.TempFile("", "test_jiri*.ensure")
	if err != nil {
		t.Errorf("failed to create test ensure file: %v", err)
	}
	defer testEnsureFile.Close()
	defer os.Remove(testEnsureFile.Name())
	_, err = testEnsureFile.Write([]byte(`
$ParanoidMode CheckPresence
$VerifiedPlatform linux-amd64
$VerifiedPlatform mac-amd64

# GN
gn/gn/${platform} git_revision:not_a_real_version
`))
	if err != nil {
		t.Errorf("failed to write test ensure file: %v", err)
	}
	testEnsureFile.Sync()
	if err := EnsureFileVerify(fakex, testEnsureFile.Name()); err == nil {
		t.Error("ensure file passed verification, should have failed")
	}
}

func TestCheckACL(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if err != nil {
		t.Errorf("bootstrap failed due to error: %v", err)
	}
	defer os.Remove(cipdPath)

	pkgMap := make(map[string]bool)
	pkgMap[cipdPkgPathA] = false
	pkgMap[cipdPkgPathB] = false
	if err := CheckPackageACL(fakex, pkgMap); err != nil {
		t.Errorf("CheckPackageACL failed due to error: %v", err)
	}

	if !pkgMap[cipdPkgPathA] {
		t.Errorf("pkg %q should be accessible, but it is not accessible by cipd", cipdPkgPathA)
	}

	if pkgMap[cipdPkgPathB] {
		t.Errorf("pkg %q should not be accessible, but it is accessible by cipd", cipdPkgPathB)
	}

}

func TestResolve(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if err != nil {
		t.Errorf("bootstrap failed due to error: %v", err)
	}
	defer os.Remove(cipdPath)

	// Write test ensure file
	testEnsureFile, err := ioutil.TempFile("", "test_jiri*.ensure")
	if err != nil {
		t.Errorf("failed to create test ensure file: %v", err)
	}
	defer testEnsureFile.Close()
	ensureFileName := testEnsureFile.Name()
	defer os.Remove(ensureFileName)
	versionFileName := ensureFileName[:len(ensureFileName)-len(".ensure")] + ".version"
	var ensureBuf bytes.Buffer
	ensureBuf.WriteString("$ResolvedVersions " + versionFileName + "\n")
	ensureBuf.WriteString(`
$ParanoidMode CheckPresence
$VerifiedPlatform linux-amd64
$VerifiedPlatform mac-amd64

# GN
gn/gn/${platform} git_revision:bdb0fd02324b120cacde634a9235405061c8ea06
`)
	_, err = testEnsureFile.Write(ensureBuf.Bytes())
	if err != nil {
		t.Errorf("failed to write test ensure file: %v", err)
	}

	testEnsureFile.Sync()
	instances, err := Resolve(fakex, testEnsureFile.Name())
	if err != nil {
		t.Errorf("resolve failed due to error: %v", err)
	}
	for _, instance := range instances {
		if val, ok := instanceIDMap[instance.PackageName]; ok {
			if val != instance.InstanceID {
				t.Errorf("instance id %q for package %q does not match the record %q",
					instance.InstanceID, instance.PackageName, val)
			}
		} else {
			t.Errorf("package %q is not found in record", instance.PackageName)
		}
	}
}

func TestExpand(t *testing.T) {
	t.Parallel()
	platforms := []Platform{
		{"linux", "amd64"},
		{"linux", "arm64"},
		{"mac", "amd64"},
	}

	tests := map[string][]string{
		"gn/gn/${platform}":                   {"gn/gn/linux-amd64", "gn/gn/linux-arm64", "gn/gn/mac-amd64"},
		"fuchsia/sysroot/${os=linux}-${arch}": {"fuchsia/sysroot/linux-amd64", "fuchsia/sysroot/linux-arm64"},
		"infra/ninja/linux-amd64":             {"infra/ninja/linux-amd64"},
	}

	for k, p := range tests {
		pkgs, err := Expand(k, platforms)
		if err != nil {
			t.Errorf("Expand faild on path %q due to error: %v", p, err)
		}
		sort.Strings(p)
		sort.Strings(pkgs)
		if !reflect.DeepEqual(p, pkgs) {
			t.Errorf("test on %q failed: expecting %v, got %v", k, p, pkgs)
		}
	}
}

func TestMustExpand(t *testing.T) {
	t.Parallel()
	tests := map[string]bool{
		"fuchsia/clang/${platform}":               true,
		"fuchsia/clang/${os}-${arch}":             true,
		"fuchsia/clang/${os=linux}-${arch=amd64}": true,
		"fuchsia/clang/linux-amd64":               false,
	}
	for k, v := range tests {
		if MustExpand(k) != v {
			t.Errorf("MustExpand failed on package %q, expecting %v got %v", k, v, MustExpand(k))
		}
	}
}

func TestDecl(t *testing.T) {
	t.Parallel()
	platforms := []Platform{
		{"linux", "amd64"},
		{"linux", "arm64"},
		{"mac", "amd64"},
	}

	tests := map[string]string{
		"fuchsia/clang/${platform}":               "fuchsia/clang/${platform=linux-amd64,linux-arm64,mac-amd64}",
		"fuchsia/clang/${os}-${arch}":             "fuchsia/clang/${os=linux,mac}-${arch=amd64,arm64}",
		"fuchsia/clang/${os=linux}-${arch}":       "fuchsia/clang/${os=linux}-${arch=amd64,arm64}",
		"fuchsia/clang/${os=linux}-${arch=amd64}": "fuchsia/clang/${os=linux}-${arch=amd64}",
		"fuchsia/clang/linux-amd64":               "fuchsia/clang/linux-amd64",
	}

	for k, v := range tests {
		cipdPath, err := Decl(k, platforms)
		if err != nil {
			t.Errorf("Decl failed on cipdPath %q due to error: %v", k, err)
		}
		if cipdPath != v {
			t.Errorf("test on %q failed: expecting %q, got %q", k, v, cipdPath)
		}
	}
}

func TestFloatingRefs(t *testing.T) {
	fakex, cleanup := xtest.NewX(t)
	defer cleanup()
	cipdPath, err := Bootstrap(fakex, fakex.CIPDPath())
	if err != nil {
		t.Errorf("bootstrap failed due to error: %v", err)
	}
	defer os.Remove(cipdPath)
	testExpects := map[PackageInstance]bool{
		{
			PackageName: "gn/gn/${platform}",
			VersionTag:  "latest",
		}: true,
		{
			PackageName: "gn/gn/${platform}",
			VersionTag:  "git_revision:bdb0fd02324b120cacde634a9235405061c8ea06",
		}: false,
	}

	platformMap := make(map[PackageInstance][]Platform)
	for k := range testExpects {
		platformMap[k] = DefaultPlatforms()
	}

	tests := make(map[PackageInstance]bool)
	for k, v := range testExpects {
		tests[k] = v
	}

	if err := CheckFloatingRefs(fakex, tests, platformMap); err != nil {
		t.Errorf("CheckFloatingRefs failed due to error: %v", err)
		return
	}

	for k, v := range tests {
		if v != testExpects[k] {
			t.Errorf("expecting %v, got %v for test %q", testExpects[k], v, k.PackageName)
		}
	}
}
