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

import (
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/verror"
)

const pkgPath = "v.io/x/ref/lib/security/audit"

var (
	errCantAuditCall = verror.Register(pkgPath+".errCantAuditCall", verror.NoRetry, "{1:}{2:} failed to audit call to {3}{:_}")
)

// NewPrincipal returns a security.Principal implementation that logs
// all private key operations of 'wrapped' to 'auditor' (i.e., all calls to
// BlessSelf, Bless, MintDischarge and Sign).
func NewPrincipal(ctx *context.T, auditor Auditor) security.Principal {
	wrapped := v23.GetPrincipal(ctx)
	return &auditingPrincipal{principal: wrapped, auditor: auditor, ctx: ctx}
}

type auditingPrincipal struct {
	principal security.Principal
	auditor   Auditor
	ctx       *context.T
}

type args []interface{}

var noBlessings security.Blessings

func (p *auditingPrincipal) Bless(key security.PublicKey, with security.Blessings, extension string, caveat security.Caveat, additionalCaveats ...security.Caveat) (security.Blessings, error) {
	blessings, err := p.principal.Bless(key, with, extension, caveat, additionalCaveats...)
	if err = p.audit(err, "Bless", addCaveats(args{key, with, extension, caveat}, additionalCaveats...), blessings); err != nil {
		return noBlessings, err
	}
	return blessings, nil
}

func (p *auditingPrincipal) BlessSelf(name string, caveats ...security.Caveat) (security.Blessings, error) {
	blessings, err := p.principal.BlessSelf(name, caveats...)
	if err = p.audit(err, "BlessSelf", addCaveats(args{name}, caveats...), blessings); err != nil {
		return noBlessings, err
	}
	return blessings, nil
}

func (p *auditingPrincipal) Sign(message []byte) (security.Signature, error) {
	// Do not save the signature itself.
	sig, err := p.principal.Sign(message)
	if err = p.audit(err, "Sign", args{message}, nil); err != nil {
		return security.Signature{}, err
	}
	return sig, nil
}

func (p *auditingPrincipal) MintDischarge(forCaveat, caveatOnDischarge security.Caveat, additionalCaveatsOnDischarge ...security.Caveat) (security.Discharge, error) {
	d, err := p.principal.MintDischarge(forCaveat, caveatOnDischarge, additionalCaveatsOnDischarge...)
	// No need to log the discharge
	if err = p.audit(err, "MintDischarge", addCaveats(args{forCaveat, caveatOnDischarge}, additionalCaveatsOnDischarge...), nil); err != nil {
		return security.Discharge{}, err
	}
	return d, nil
}

func (p *auditingPrincipal) PublicKey() security.PublicKey         { return p.principal.PublicKey() }
func (p *auditingPrincipal) Roots() security.BlessingRoots         { return p.principal.Roots() }
func (p *auditingPrincipal) BlessingStore() security.BlessingStore { return p.principal.BlessingStore() }

func (p *auditingPrincipal) audit(err error, method string, args args, result interface{}) error {
	if err != nil {
		return err
	}
	entry := Entry{Method: method, Timestamp: time.Now()}
	if len(args) > 0 {
		entry.Arguments = []interface{}(args)
	}
	if result != nil {
		entry.Results = []interface{}{result}
	}
	if err := p.auditor.Audit(p.ctx, entry); err != nil {
		return verror.New(errCantAuditCall, nil, method, err)
	}
	return nil
}

func addCaveats(args args, caveats ...security.Caveat) args {
	for _, c := range caveats {
		args = append(args, c)
	}
	return args
}
