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

import (
	"encoding/json"
	"os"
	"strings"

	"v.io/v23/naming"
	"v.io/v23/services/application"
	"v.io/x/ref/test/v23tests"
)

//go:generate v23 test generate

func helper(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, cmd string, args ...string) string {
	args = append([]string{cmd}, args...)
	inv := clientBin.Start(args...)
	out := inv.Output()
	err := inv.Wait(os.Stdout, os.Stderr)
	if err != nil && !expectError {
		i.Fatalf("%s %q failed: %v\n%v", clientBin.Path(), strings.Join(args, " "), err, out)
	}
	if err == nil && expectError {
		i.Fatalf("%s %q did not fail when it should", clientBin.Path(), strings.Join(args, " "))
	}
	return strings.TrimSpace(out)

}

func matchEnvelope(i *v23tests.T, clientBin *v23tests.Binary, expectError bool, name, suffix string) string {
	return helper(i, clientBin, expectError, "match", naming.Join(name, suffix), "test-profile")
}

func putEnvelope(i *v23tests.T, clientBin *v23tests.Binary, name, suffix, envelope string) string {
	return helper(i, clientBin, false, "put", naming.Join(name, suffix), "test-profile", envelope)
}

func removeEnvelope(i *v23tests.T, clientBin *v23tests.Binary, name, suffix string) string {
	return helper(i, clientBin, false, "remove", naming.Join(name, suffix), "test-profile")
}

func binaryWithCredentials(i *v23tests.T, extension, pkgpath string) *v23tests.Binary {
	creds, err := i.Shell().NewChildCredentials(extension)
	if err != nil {
		i.Fatalf("NewCustomCredentials (for %q) failed: %v", pkgpath, err)
	}
	b := i.BuildV23Pkg(pkgpath)
	return b.WithStartOpts(b.StartOpts().WithCustomCredentials(creds))
}

func V23TestApplicationRepository(i *v23tests.T) {
	v23tests.RunRootMT(i, "--v23.tcp.address=127.0.0.1:0")

	// Start the application repository.
	appRepoName := "test-app-repo"
	binaryWithCredentials(i, "applicationd", "v.io/x/ref/services/application/applicationd").Start(
		"-name="+appRepoName,
		"-store="+i.NewTempDir(""),
		"-v=2",
		"-v23.tcp.address=127.0.0.1:0")

	// Build the client binary (must be a delegate of the server to pass
	// the default authorization policy).
	clientBin := binaryWithCredentials(i, "applicationd/client", "v.io/x/ref/services/application/application")

	// Generate publisher blessings
	publisher, err := i.Shell().NewChildCredentials("publisher")
	if err != nil {
		i.Fatal(err)
	}
	sig, err := publisher.Principal().Sign([]byte("binarycontents"))
	if err != nil {
		i.Fatal(err)
	}
	// Create an application envelope.
	appRepoSuffix := "test-application/v1"
	appEnvelopeFile := i.NewTempFile()
	wantEnvelope, err := json.MarshalIndent(application.Envelope{
		Title: "title",
		Binary: application.SignedFile{
			File:      "foo",
			Signature: sig,
		},
		Publisher: publisher.Principal().BlessingStore().Default(),
	}, "", "  ")
	if err != nil {
		i.Fatal(err)
	}
	if _, err := appEnvelopeFile.Write([]byte(wantEnvelope)); err != nil {
		i.Fatalf("Write() failed: %v", err)
	}
	putEnvelope(i, clientBin, appRepoName, appRepoSuffix, appEnvelopeFile.Name())

	// Match the application envelope.
	if got, want := matchEnvelope(i, clientBin, false, appRepoName, appRepoSuffix), string(wantEnvelope); got != want {
		i.Fatalf("unexpected output: got %v, want %v", got, want)
	}

	// Remove the application envelope.
	removeEnvelope(i, clientBin, appRepoName, appRepoSuffix)

	// Check that the application envelope no longer exists.
	matchEnvelope(i, clientBin, true, appRepoName, appRepoSuffix)
}
