// 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 principal implements a principal manager that maps origins to
// vanadium principals.
//
// Each instance of wspr is expected to have a single (human) user at a time
// that will be signed in and using various apps. A user may have different
// Blessings, which in practice will be done by having multiple accounts
// across many Blessing providers (e.g., google, facebook, etc). This is similar
// to having a master identity that is linked to multiple identities in today's
// technology. In our case, each user account is represented as a Blessing
// obtained from the corresponding Blessing provider.
//
// Every app/origin is a different principal and has its own public/private key
// pair, represented by a Principal object that is created by this manager on
// the app's behalf. For each app/origin, the user may choose which account to
// use for the app, which results in a blessing generated for the app principal
// using the selected account's blessing.
//
// For example, a user Alice may have an account at Google and Facebook,
// resulting in the blessings "google/alice@gmail.com" and
// "facebook/alice@facebook.com". She may then choose to use her Google account
// for the "googleplay" app, which would result in the creation of a new
// principal for that app and a blessing "google/alice@gmail.com/googleplay" for
// that principal.
//
// The principal manager only serializes the mapping from apps to (chosen)
// accounts and the account information, but not the private keys for each app.
package principal

import (
	"bytes"
	"fmt"
	"io"
	"net/url"
	"sync"
	"time"

	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/v23/vom"
	vsecurity "v.io/x/ref/lib/security"
	"v.io/x/ref/lib/security/serialization"
)

// permissions is a set of a permissions given to an app, containing the account
// the app has access to and the caveats associated with it.
type permissions struct {
	// Account is the name of the account given to the app.
	Account string
	// Caveats that must be added to the blessing generated for the app from
	// the account's blessing.
	Caveats []security.Caveat
	// Expirations is the expiration times of any expiration caveats.  Must
	// be unix-time so it can be persisted.
	Expirations []int64
}

// persistentState is the state of the manager that will be persisted to disk.
type persistentState struct {
	// A mapping of origins to the permissions provided for the origin (such as
	// caveats and the account given to the origin)
	Origins map[string]permissions

	// A set of accounts that maps from an account name to the Blessings associated
	// with the account.
	Accounts map[string]security.Blessings
}

const pkgPath = "v.io/x/ref/services/wspr/internal/principal"

// Errors.
var (
	errUnknownAccount                   = verror.Register(pkgPath+".errUnknownAccount", verror.NoRetry, "{1:}{2:} unknown account{:_}")
	errFailedToCreatePrincipal          = verror.Register(pkgPath+".errFailedToCreatePrincipal", verror.NoRetry, "{1:}{2:} failed to create new principal{:_}")
	errFailedToConstructBlessings       = verror.Register(pkgPath+".errFailedToConstructBlessings", verror.NoRetry, "{1:}{2:} failed to construct Blessings to bless with{:_}")
	errFailedToBlessPrincipal           = verror.Register(pkgPath+".errFailedToBlessPrincipal", verror.NoRetry, "{1:}{2:} failed to bless new principal with the provided account{:_}")
	errFailedToSetDefaultBlessings      = verror.Register(pkgPath+".errFailedToSetDefaultBlessings", verror.NoRetry, "{1:}{2:} failed to set account blessings as default{:_}")
	errFailedToSetAllPrincipalBlessings = verror.Register(pkgPath+".errFailedToSetAllPrincipalBlessings", verror.NoRetry, "{1:}{2:} failed to set account blessings for all principals{:_}")
	errFailedToAddRoots                 = verror.Register(pkgPath+".errFailedToAddRoots", verror.NoRetry, "{1:}{2:} failed to add roots of account blessing{:_}")
)

// bufferCloser implements io.ReadWriteCloser.
type bufferCloser struct {
	bytes.Buffer
}

func (*bufferCloser) Close() error {
	return nil
}

// InMemorySerializer implements SerializerReaderWriter. This Serializer should only
// be used in tests.
type InMemorySerializer struct {
	data      bufferCloser
	signature bufferCloser
	hasData   bool
}

func (s *InMemorySerializer) Readers() (io.ReadCloser, io.ReadCloser, error) {
	if !s.hasData {
		return nil, nil, nil
	}
	return &s.data, &s.signature, nil
}

func (s *InMemorySerializer) Writers() (io.WriteCloser, io.WriteCloser, error) {
	s.hasData = true
	s.data.Reset()
	s.signature.Reset()
	return &s.data, &s.signature, nil
}

// PrincipalManager manages app principals. We only serialize the accounts
// associated with this principal manager and the mapping of apps to permissions
// that they were given.
type PrincipalManager struct {
	mu    sync.Mutex
	state persistentState

	// root is the Principal that hosts this PrincipalManager.
	root security.Principal

	serializer vsecurity.SerializerReaderWriter

	// Dummy account name
	// TODO(bjornick, nlacasse): Remove this once the tests no longer need
	// it.
	dummyAccount string
}

// NewPrincipalManager returns a new PrincipalManager that creates new principals
// for various app/origins and blessed them with blessings for the provided 'root'
// principal from the specified blessing provider.
// .
//
// It is initialized by reading data from the 'serializer' passed in which must
// be non-nil.
func NewPrincipalManager(root security.Principal, serializer vsecurity.SerializerReaderWriter) (*PrincipalManager, error) {
	result := &PrincipalManager{
		state: persistentState{
			Origins:  map[string]permissions{},
			Accounts: map[string]security.Blessings{},
		},
		root:       root,
		serializer: serializer,
	}
	data, signature, err := serializer.Readers()
	if err != nil {
		return nil, err
	}
	if (data == nil) || (signature == nil) {
		// No serialized data exists, returning an empty PrincipalManager.
		return result, nil
	}
	vr, err := serialization.NewVerifyingReader(data, signature, root.PublicKey())
	if err != nil {
		return nil, err
	}

	decoder, err := vom.NewDecoder(vr)

	if err != nil {
		return nil, err
	}

	if err := decoder.Decode(&result.state); err != nil {
		return nil, err
	}
	return result, nil
}

func (i *PrincipalManager) save() error {
	data, signature, err := i.serializer.Writers()
	if err != nil {
		return err
	}
	swc, err := serialization.NewSigningWriteCloser(data, signature, i.root, nil)
	if err != nil {
		return err
	}

	encoder, err := vom.NewEncoder(swc)

	if err != nil {
		return err
	}
	if err := encoder.Encode(i.state); err != nil {
		return err
	}
	return swc.Close()
}

// Principal returns the Principal for an origin or an error if there is
// no linked account.
func (i *PrincipalManager) Principal(origin string) (security.Principal, error) {
	i.mu.Lock()
	defer i.mu.Unlock()
	perm, found := i.state.Origins[origin]
	if !found {
		return nil, verror.New(verror.ErrNoExist, nil, origin)
	}
	blessings, found := i.state.Accounts[perm.Account]
	if !found {
		return nil, verror.New(errUnknownAccount, nil, perm.Account)
	}
	return i.createPrincipal(origin, blessings, perm.Caveats)
}

// OriginHasAccount returns true iff the origin has been associated with
// permissions and an account for which blessings have been obtained from a
// blessing provider, and if the blessings have no expiration caveats or an
// expiration in the future.
func (i *PrincipalManager) OriginHasAccount(origin string) bool {
	i.mu.Lock()
	defer i.mu.Unlock()
	perm, found := i.state.Origins[origin]
	if !found {
		return false
	}

	// Check if all expiration caveats are satisfied.
	now := time.Now()
	for _, unixExp := range perm.Expirations {
		exp := time.Unix(unixExp, 0)
		if exp.Before(now) {
			return false
		}
	}

	_, found = i.state.Accounts[perm.Account]
	return found
}

// BlessingsForAccount returns the Blessing associated with the provided
// account.  It returns an error if account does not exist.
//
// TODO(ataly, ashankar, bjornick): Modify this method to allow searching
// for accounts from a specific root blessing provider. One option is
// that the method could take a set of root blessing providers as argument
// and then return accounts whose blessings are from one of these providers.
func (i *PrincipalManager) BlessingsForAccount(account string) (security.Blessings, error) {
	i.mu.Lock()
	defer i.mu.Unlock()

	blessings, found := i.state.Accounts[account]
	if !found {
		return security.Blessings{}, verror.New(errUnknownAccount, nil, account)
	}
	return blessings, nil
}

// AddAccount associates the provided Blessing with the provided account.
func (i *PrincipalManager) AddAccount(account string, blessings security.Blessings) error {
	i.mu.Lock()
	defer i.mu.Unlock()

	old, existed := i.state.Accounts[account]
	i.state.Accounts[account] = blessings

	if err := i.save(); err != nil {
		delete(i.state.Accounts, account)
		if existed {
			i.state.Accounts[account] = old
		}
		return err
	}
	return nil
}

// AddOrigin adds an origin to the manager linked to the given account.
func (i *PrincipalManager) AddOrigin(origin string, account string, caveats []security.Caveat, expirations []time.Time) error {
	i.mu.Lock()
	defer i.mu.Unlock()
	if _, found := i.state.Accounts[account]; !found {
		return verror.New(errUnknownAccount, nil, account)
	}

	unixExpirations := []int64{}
	for _, exp := range expirations {
		unixExpirations = append(unixExpirations, exp.Unix())
	}

	old, existed := i.state.Origins[origin]
	i.state.Origins[origin] = permissions{account, caveats, unixExpirations}

	if err := i.save(); err != nil {
		delete(i.state.Origins, origin)
		if existed {
			i.state.Origins[origin] = old
		}
		return err
	}
	return nil
}

func (i *PrincipalManager) createPrincipal(origin string, withBlessings security.Blessings, caveats []security.Caveat) (security.Principal, error) {
	ret, err := vsecurity.NewPrincipal()
	if err != nil {
		return nil, verror.New(errFailedToCreatePrincipal, nil, err)
	}

	if len(caveats) == 0 {
		caveats = append(caveats, security.UnconstrainedUse())
	}
	// Origins have the form protocol://hostname:port, which is not a valid
	// blessing extension. Hence we must url-encode.
	blessings, err := i.root.Bless(ret.PublicKey(), withBlessings, url.QueryEscape(origin), caveats[0], caveats[1:]...)
	if err != nil {
		return nil, verror.New(errFailedToBlessPrincipal, nil, err)
	}

	if err := ret.BlessingStore().SetDefault(blessings); err != nil {
		return nil, verror.New(errFailedToSetDefaultBlessings, nil, err)
	}
	if _, err := ret.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
		return nil, verror.New(errFailedToSetAllPrincipalBlessings, nil, err)
	}
	if err := ret.AddToRoots(blessings); err != nil {
		return nil, verror.New(errFailedToAddRoots, nil, err)
	}
	return ret, nil
}

// Add dummy account with default blessings, for use by unauthenticated
// clients.
// TODO(nlacasse, bjornick): This should go away once unauthenticate clients
// are no longer allowed.
func (i *PrincipalManager) DummyAccount() (string, error) {
	if i.dummyAccount == "" {
		// Note: We only set i.dummyAccount once the account has been
		// successfully created.  Otherwise, if an error occurs, the
		// next time this function is called it the account won't exist
		// but this function will return the name of the account
		// without trying to create it.
		dummyAccount := "unauthenticated-dummy-account"
		blessings, err := i.root.BlessSelf(dummyAccount)
		if err != nil {
			return "", fmt.Errorf("i.root.BlessSelf(%v) failed: %v", dummyAccount, err)
		}

		if err := i.AddAccount(dummyAccount, blessings); err != nil {
			return "", fmt.Errorf("browspr.principalManager.AddAccount(%v, %v) failed: %v", dummyAccount, blessings, err)
		}
		i.dummyAccount = dummyAccount
	}
	return i.dummyAccount, nil
}
