// Copyright 2015 The Vanadium 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 globsuid_test

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"syscall"
	"testing"

	"v.io/v23"
	"v.io/v23/naming"
	"v.io/v23/services/application"
	"v.io/v23/services/device"
	"v.io/v23/services/repository"
	"v.io/v23/verror"

	"v.io/x/ref/services/device/internal/impl"
	"v.io/x/ref/services/device/internal/impl/utiltest"
	"v.io/x/ref/services/internal/binarylib"
	"v.io/x/ref/services/internal/servicetest"
	"v.io/x/ref/test/testutil"
)

func TestDownloadSignatureMatch(t *testing.T) {
	ctx, shutdown := utiltest.InitForTest()
	defer shutdown()

	sh, deferFn := servicetest.CreateShellAndMountTable(t, ctx, nil)
	defer deferFn()

	binaryVON := "binary"
	pkgVON := naming.Join(binaryVON, "testpkg")
	defer utiltest.StartRealBinaryRepository(t, ctx, binaryVON)()

	up := testutil.RandomBytes(testutil.Intn(5 << 20))
	mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
	sig, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo)
	if err != nil {
		t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
	}

	// Upload packages for this application
	tmpdir, err := ioutil.TempDir("", "test-package-")
	if err != nil {
		t.Fatalf("ioutil.TempDir failed: %v", err)
	}
	defer os.RemoveAll(tmpdir)
	pkgContents := testutil.RandomBytes(testutil.Intn(5 << 20))
	if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
		t.Fatalf("ioutil.WriteFile failed: %v", err)
	}
	pkgSig, err := binarylib.UploadFromDir(ctx, pkgVON, tmpdir)
	if err != nil {
		t.Fatalf("binarylib.UploadFromDir failed: %v", err)
	}

	// Start the application repository
	envelope, serverStop := utiltest.StartApplicationRepository(ctx)
	defer serverStop()

	root, cleanup := servicetest.SetupRootDir(t, "devicemanager")
	defer cleanup()
	if err := impl.SaveCreatorInfo(root); err != nil {
		t.Fatal(err)
	}

	// Create a script wrapping the test target that implements suidhelper.
	helperPath := utiltest.GenerateSuidHelperScript(t, root)

	// Set up the device manager.  Since we won't do device manager updates,
	// don't worry about its application envelope and current link.
	dmh := servicetest.RunCommand(t, sh, nil, utiltest.DeviceManagerCmd, "dm", root, helperPath, "unused_app_repo_name", "unused_curr_link")
	pid := servicetest.ReadPID(t, dmh)
	defer syscall.Kill(pid, syscall.SIGINT)
	utiltest.ClaimDevice(t, ctx, "claimable", "dm", "mydevice", utiltest.NoPairingToken)

	publisher, err := v23.GetPrincipal(ctx).BlessSelf("publisher")
	if err != nil {
		t.Fatalf("Failed to generate publisher blessings:%v", err)
	}
	*envelope = application.Envelope{
		Binary: application.SignedFile{
			File:      naming.Join(binaryVON, "testbinary"),
			Signature: *sig,
		},
		Publisher: publisher,
		Packages: map[string]application.SignedFile{
			"pkg": application.SignedFile{
				File:      pkgVON,
				Signature: *pkgSig,
			},
		},
	}
	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); err != nil {
		t.Fatalf("Failed to Install app:%v", err)
	}

	// Verify that when the binary is corrupted, signature verification fails.
	up[0] = up[0] ^ 0xFF
	if err := binarylib.Delete(ctx, naming.Join(binaryVON, "testbinary")); err != nil {
		t.Fatalf("Delete(%v) failed:%v", binaryVON, err)
	}
	if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
		t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
	}
	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
		t.Fatalf("Failed to verify signature mismatch for binary:%v. Got errorid=%v[%v], want errorid=%v", binaryVON, verror.ErrorID(err), err, impl.ErrOperationFailed.ID)
	}

	// Restore the binary and verify that installation succeeds.
	up[0] = up[0] ^ 0xFF
	if err := binarylib.Delete(ctx, naming.Join(binaryVON, "testbinary")); err != nil {
		t.Fatalf("Delete(%v) failed:%v", binaryVON, err)
	}
	if _, err := binarylib.Upload(ctx, naming.Join(binaryVON, "testbinary"), up, mediaInfo); err != nil {
		t.Fatalf("Upload(%v) failed:%v", binaryVON, err)
	}
	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); err != nil {
		t.Fatalf("Failed to Install app:%v", err)
	}

	// Verify that when the package contents are corrupted, signature verification fails.
	pkgContents[0] = pkgContents[0] ^ 0xFF
	if err := binarylib.Delete(ctx, pkgVON); err != nil {
		t.Fatalf("Delete(%v) failed:%v", pkgVON, err)
	}
	if err := os.Remove(filepath.Join(tmpdir, "pkg.txt")); err != nil {
		t.Fatalf("Remove(%v) failed:%v", filepath.Join(tmpdir, "pkg.txt"), err)
	}
	if err := ioutil.WriteFile(filepath.Join(tmpdir, "pkg.txt"), pkgContents, 0600); err != nil {
		t.Fatalf("ioutil.WriteFile failed: %v", err)
	}
	if _, err = binarylib.UploadFromDir(ctx, pkgVON, tmpdir); err != nil {
		t.Fatalf("binarylib.UploadFromDir failed: %v", err)
	}
	if _, err := utiltest.AppStub().Install(ctx, utiltest.MockApplicationRepoName, device.Config{}, nil); verror.ErrorID(err) != impl.ErrOperationFailed.ID {
		t.Fatalf("Failed to verify signature mismatch for package:%v", pkgVON)
	}
}
