// Package security contains utility testing functions related to
// security.
package security

import (
	"io/ioutil"
	"os"

	vsecurity "veyron.io/veyron/veyron/security"

	"veyron.io/veyron/veyron2/security"
	"veyron.io/veyron/veyron2/services/security/access"
)

// NewVeyronCredentials generates a directory with a new principal
// that can be used as a value for the VEYRON_CREDENTIALS environment
// variable to initialize a Runtime.
//
// The principal created uses a blessing from 'parent', with the extension
// 'name' as its default blessing.
//
// It returns the path to the directory created.
func NewVeyronCredentials(parent security.Principal, name string) string {
	dir, err := ioutil.TempDir("", "veyron_credentials")
	if err != nil {
		panic(err)
	}
	p, err := vsecurity.LoadPersistentPrincipal(dir, nil)
	if err != nil {
		if p, err = vsecurity.CreatePersistentPrincipal(dir, nil); err != nil {
			panic(err)
		}
	}
	blessings, err := parent.Bless(p.PublicKey(), parent.BlessingStore().Default(), name, security.UnconstrainedUse())
	if err != nil {
		panic(err)
	}
	SetDefaultBlessings(p, blessings)
	return dir
}

// NewPrincipal creates a new security.Principal.
//
// It also creates self-certified blessings for defaultBlessings and
// marks the union of these blessings as default and shareable with all
// peers on the principal's blessing store.
func NewPrincipal(defaultBlessings ...string) security.Principal {
	p, err := vsecurity.NewPrincipal()
	if err != nil {
		panic(err)
	}
	var def security.Blessings
	for _, blessing := range defaultBlessings {
		b, err := p.BlessSelf(blessing)
		if err != nil {
			panic(err)
		}
		if def, err = security.UnionOfBlessings(def, b); err != nil {
			panic(err)
		}
	}
	if def != nil {
		SetDefaultBlessings(p, def)
	}
	return p
}

// SetDefaultBlessings updates the BlessingStore and BlessingRoots of p
// so that:
// (1) b is revealed to all clients that connect to Servers operated
// by 'p' (BlessingStore.Default)
// (2) b is revealed  to all servers that clients connect to on behalf
// of p (BlessingStore.Set(..., security.AllPrincipals))
// (3) p recognizes all blessings that have the same root certificate as b.
// (AddToRoots)
func SetDefaultBlessings(p security.Principal, b security.Blessings) {
	if err := p.BlessingStore().SetDefault(b); err != nil {
		panic(err)
	}
	if _, err := p.BlessingStore().Set(b, security.AllPrincipals); err != nil {
		panic(err)
	}
	if err := p.AddToRoots(b); err != nil {
		panic(err)
	}
}

// SaveACLToFile saves the provided ACL in JSON format to a randomly created
// temporary file, and returns the path to the file. This function is meant
// to be used for testing purposes only, it panics if there is an error. The
// caller must ensure that the created file is removed once it is no longer needed.
func SaveACLToFile(acl access.TaggedACLMap) string {
	f, err := ioutil.TempFile("", "saved_acl")
	if err != nil {
		panic(err)
	}
	defer f.Close()
	if err := acl.WriteTo(f); err != nil {
		defer os.Remove(f.Name())
		panic(err)
	}
	return f.Name()
}

// IDProvider is a convenience wrapper over security.Principal that
// makes a Principal act as an "identity provider" (i.e., provides
// other principals with a blessing from it).
type IDProvider struct {
	p security.Principal
	b security.Blessings
}

func NewIDProvider(name string) *IDProvider {
	p, err := vsecurity.NewPrincipal()
	if err != nil {
		panic(err)
	}
	b, err := p.BlessSelf(name)
	if err != nil {
		panic(err)
	}
	return &IDProvider{p, b}
}

// Bless sets up the provided principal to use blessings from idp as its
// default.
func (idp *IDProvider) Bless(who security.Principal, extension string, caveats ...security.Caveat) error {
	blessings, err := idp.NewBlessings(who, extension, caveats...)
	if err != nil {
		return err
	}
	SetDefaultBlessings(who, blessings)
	return nil
}

// NewBlessings returns Blessings that extend the identity provider's blessing
// with 'extension' and binds it to 'p.PublicKey'.
func (idp *IDProvider) NewBlessings(p security.Principal, extension string, caveats ...security.Caveat) (security.Blessings, error) {
	if len(caveats) == 0 {
		caveats = append(caveats, security.UnconstrainedUse())
	}
	blessings, err := idp.p.Bless(p.PublicKey(), idp.b, extension, caveats[0], caveats[1:]...)
	if err != nil {
		return nil, err
	}
	return blessings, nil
}

// PublicKey is the public key of the identity provider.
func (idp *IDProvider) PublicKey() security.PublicKey {
	return idp.p.PublicKey()
}
