// Package revocation provides tools to create and manage revocation caveats.
package revocation

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"path/filepath"
	"strconv"
	"sync"
	"time"

	"veyron.io/veyron/veyron/services/identity/util"
	"veyron.io/veyron/veyron2/security"
	"veyron.io/veyron/veyron2/vom"
)

// RevocationManager persists information for revocation caveats to provided discharges and allow for future revocations.
type RevocationManager struct {
	caveatMap *util.DirectoryStore // Map of blessed identity's caveats.  ThirdPartyCaveatID -> revocationCaveatID
}

var revocationMap *util.DirectoryStore
var revocationLock sync.RWMutex

// NewCaveat returns a security.ThirdPartyCaveat for which discharges will be
// issued iff Revoke has not been called for the returned caveat.
func (r *RevocationManager) NewCaveat(discharger security.PublicKey, dischargerLocation string) (security.ThirdPartyCaveat, error) {
	var revocation [16]byte
	if _, err := rand.Read(revocation[:]); err != nil {
		return nil, err
	}
	restriction, err := security.NewCaveat(revocationCaveat(revocation))
	if err != nil {
		return nil, err
	}
	cav, err := security.NewPublicKeyCaveat(discharger, dischargerLocation, security.ThirdPartyRequirements{}, restriction)
	if err != nil {
		return nil, err
	}
	if err = r.caveatMap.Put(hex.EncodeToString([]byte(cav.ID())), hex.EncodeToString(revocation[:])); err != nil {
		return nil, err
	}
	return cav, nil
}

// Revoke disables discharges from being issued for the provided third-party caveat.
func (r *RevocationManager) Revoke(caveatID string) error {
	token, err := r.caveatMap.Get(hex.EncodeToString([]byte(caveatID)))
	if err != nil {
		return err
	}
	return revocationMap.Put(token, strconv.FormatInt(time.Now().Unix(), 10))
}

// GetRevocationTimestamp returns the timestamp at which a caveat was revoked.
// If the caveat wasn't revoked returns nil
func (r *RevocationManager) GetRevocationTime(caveatID string) *time.Time {
	token, err := r.caveatMap.Get(hex.EncodeToString([]byte(caveatID)))
	if err != nil {
		return nil
	}
	timestamp, err := revocationMap.Get(token)
	if err != nil {
		return nil
	}
	unix_int, err := strconv.ParseInt(timestamp, 10, 64)
	if err != nil {
		return nil
	}
	revocationTime := time.Unix(unix_int, 0)
	return &revocationTime
}

type revocationCaveat [16]byte

func (cav revocationCaveat) Validate(security.Context) error {
	revocationLock.RLock()
	if revocationMap == nil {
		revocationLock.RUnlock()
		return fmt.Errorf("missing call to NewRevocationManager")
	}
	revocationLock.RUnlock()
	if revocationMap.Exists(hex.EncodeToString(cav[:])) {
		return fmt.Errorf("revoked")
	}
	return nil
}

// NewRevocationManager returns a RevocationManager that persists information about
// revocationCaveats and allows for revocation and caveat creation.
// This function can only be called once because of the use of global variables.
func NewRevocationManager(dir string) (*RevocationManager, error) {
	revocationLock.Lock()
	defer revocationLock.Unlock()
	if revocationMap != nil {
		return nil, fmt.Errorf("NewRevocationManager can only be called once")
	}
	// If empty string return nil revocationManager
	if len(dir) == 0 {
		return nil, nil
	}
	caveatMap, err := util.NewDirectoryStore(filepath.Join(dir, "caveat_dir"))
	if err != nil {
		return nil, err
	}
	revocationMap, err = util.NewDirectoryStore(filepath.Join(dir, "revocation_dir"))
	if err != nil {
		return nil, err
	}
	return &RevocationManager{caveatMap}, nil
}

func init() {
	vom.Register(revocationCaveat{})
}
