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

// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"fmt"
	"reflect"
	"runtime"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/x/lib/cmdline"
	"v.io/x/ref"
	"v.io/x/ref/lib/v23cmd"

	_ "v.io/x/ref/runtime/factories/generic"
)

func newKey() security.PublicKey {
	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		panic(err)
	}
	return security.NewECDSAPublicKey(&k.PublicKey)
}

func main() {
	cmdline.HideGlobalFlagsExcept()
	cmdline.Main(cmdTestPrincipal)
}

var cmdTestPrincipal = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runTestPrincipal),
	Name:   "test_principal",
	Short:  "Runs tests against a principal",
	Long:   "Command test_principal runs tests against a principal.",
}

func runTestPrincipal(ctx *context.T, env *cmdline.Env, args []string) error {
	var errors []string
	errorf := func(format string, args ...interface{}) {
		_, file, line, _ := runtime.Caller(1)
		errors = append(errors, fmt.Sprintf("%v:%d: %v", file, line, fmt.Sprintf(format, args...)))
	}
	p := v23.GetPrincipal(ctx)
	// Make sure we're running under a pristine agent to begin with.
	// The agent aims to be transparent, so use a collection of heuristics
	// to detect this.
	if got := env.Vars[ref.EnvCredentials]; len(got) != 0 {
		errorf("%v environment variable is unexpectedly set", ref.EnvCredentials)
	}
	if got := env.Vars[ref.EnvAgentPath]; len(got) == 0 {
		errorf("%v environment variable is not set", ref.EnvAgentPath)
	}
	// A pristine agent has a single blessing "agent_principal" (from agentd/main.go).
	if got, want := security.BlessingNames(p, p.BlessingStore().Default()), []string{"agent_principal"}; !reflect.DeepEqual(got, want) {
		errorf("Got %v want %v", got, want)
	}

	// BlessSelf
	b, err := p.BlessSelf("batman")
	if err != nil {
		errorf("BlessSelf: %v", err)
	}
	// Bless
	if _, err := p.Bless(newKey(), b, "delegate", security.UnconstrainedUse()); err != nil {
		errorf("Bless: %v", err)
	}
	// Sign & PublicKey
	signature, err := p.Sign([]byte("bugs bunny"))
	if err != nil {
		errorf("Sign: %v", err)
	}
	if !signature.Verify(p.PublicKey(), []byte("bugs bunny")) {
		errorf("signature.Verify: %v", err)
	}
	// MintDischarge
	cav, err := security.NewMethodCaveat("method")
	if err != nil {
		errorf("security.MethodCaveat: %v", err)
	}
	tpcav, err := security.NewPublicKeyCaveat(p.PublicKey(), "location", security.ThirdPartyRequirements{}, cav)
	if err != nil {
		errorf("security.NewPublicKeyCaveat: %v", err)
	}
	dis, err := p.MintDischarge(tpcav, cav)
	if err != nil {
		errorf("MintDischarge: %v", err)
	}
	// BlessingRoots
	keybytes, err := p.PublicKey().MarshalBinary()
	if err != nil {
		errorf("Failed to marshal public key: %v", err)
	}
	if err := p.Roots().Recognized(keybytes, "batman"); err == nil {
		errorf("Roots().Recognized returned nil")
	}
	if err := security.AddToRoots(p, b); err != nil {
		errorf("AddToRoots: %v", err)
	}
	if err := p.Roots().Recognized(keybytes, "batman"); err != nil {
		errorf("Roots().Recognized: %v", err)
	}
	// BlessingStore: Defaults
	if err := p.BlessingStore().SetDefault(security.Blessings{}); err != nil {
		errorf("BlessingStore().SetDefault: %v", err)
	}
	if def := p.BlessingStore().Default(); !def.IsZero() {
		errorf("BlessingStore().Default returned %v, want empty", def)
	}
	if err := p.BlessingStore().SetDefault(b); err != nil {
		errorf("BlessingStore().SetDefault: %v", err)
	}
	if def := p.BlessingStore().Default(); !reflect.DeepEqual(def, b) {
		errorf("BlessingStore().Default returned [%v], want [%v]", def, b)
	}
	// BlessingStore: Set & ForPeer
	// First, clear out the self-generated default of the blessing store.
	if _, err := p.BlessingStore().Set(security.Blessings{}, security.AllPrincipals); err != nil {
		errorf("BlessingStore().Set(nil, %q): %v", security.AllPrincipals, err)
	}
	if forpeer := p.BlessingStore().ForPeer("superman/friend"); !forpeer.IsZero() {
		errorf("BlessingStore().ForPeer unexpectedly returned %v", forpeer)
	}
	if old, err := p.BlessingStore().Set(b, "superman"); err != nil {
		errorf("BlessingStore().Set returned (%v, %v)", old, err)
	}
	if forpeer := p.BlessingStore().ForPeer("superman/friend"); !reflect.DeepEqual(forpeer, b) {
		errorf("BlessingStore().ForPeer returned %v and not %v", forpeer, b)
	}
	p.BlessingStore().CacheDischarge(dis, tpcav, security.DischargeImpetus{})
	if got := p.BlessingStore().Discharge(tpcav, security.DischargeImpetus{}); !dis.Equivalent(got) {
		errorf("BlessingStore().Discharges returned %#v want %#v", got, dis)
	}
	p.BlessingStore().ClearDischarges(dis)
	if got := p.BlessingStore().Discharge(tpcav, security.DischargeImpetus{}); got.ID() != "" {
		errorf("BlessingStore().Discharges returned %#v want empty", got)
	}

	if len(errors) > 0 {
		// Print out all errors and exit with failure.
		for _, e := range errors {
			fmt.Fprintln(env.Stderr, e)
		}
		return cmdline.ErrExitCode(1)
	}
	return nil
}
