package security

import (
	"crypto/ecdsa"
	"errors"
	"fmt"
	"os"
	"path"
	"reflect"
	"sync"

	"veyron/security/serialization"

	"veyron2/security"
	"veyron2/security/wire"
	"veyron2/vom"
)

const (
	dataFile      = "blessingstore.data"
	signatureFile = "blessingstore.sig"
)

var (
	errStoreAddMismatch = errors.New("public key does not match that of existing PublicIDs in the store")
	errNoMatchingIDs    = errors.New("no matching PublicIDs")
)

func errCombine(err error) error {
	return fmt.Errorf("could not combine matching PublicIDs: %s", err)
}

func saveErr(err error) error {
	return fmt.Errorf("could not save PublicIDStore: %s", err)
}

type taggedIDStore map[security.PublicID][]security.BlessingPattern

type persistentState struct {
	// Store contains a set of PublicIDs mapped to a set of (peer) patterns. The
	// patterns indicate the set of peers against whom the PublicID can be used.
	// All PublicIDs in the store must have the same public key.
	Store taggedIDStore
	// DefaultPattern is the default BlessingPattern to be used to select
	// PublicIDs from the store in absence of any other search criterea.
	DefaultPattern security.BlessingPattern
}

// publicIDStore implements security.PublicIDStore.
type publicIDStore struct {
	state     persistentState
	publicKey *ecdsa.PublicKey
	params    *PublicIDStoreParams
	mu        sync.RWMutex
}

func (s *publicIDStore) addTaggedID(id security.PublicID, peerPattern security.BlessingPattern) ([]security.PublicID, error) {
	var updatedIDs []security.PublicID
	switch p := id.(type) {
	case *setPublicID:
		for _, ip := range *p {
			ids, err := s.addTaggedID(ip, peerPattern)
			if err != nil {
				return updatedIDs, err
			}
			updatedIDs = append(updatedIDs, ids...)
		}
	default:
		// TODO(ataly): Once we get rid of FakePublicID, force this case to be exactly
		// *chainPublicID.
		for _, pattern := range s.state.Store[id] {
			if pattern == peerPattern {
				return updatedIDs, nil
			}
		}
		s.state.Store[id] = append(s.state.Store[id], peerPattern)
		updatedIDs = append(updatedIDs, id)
	}
	return updatedIDs, nil
}

func (s *publicIDStore) revert(updatedIDs []security.PublicID) {
	for _, id := range updatedIDs {
		s.state.Store[id] = s.state.Store[id][:len(s.state.Store[id])-1]
	}
}

func (s *publicIDStore) Add(id security.PublicID, peerPattern security.BlessingPattern) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	publicKeyIsNil := s.publicKey == nil
	if !publicKeyIsNil && !reflect.DeepEqual(id.PublicKey(), s.publicKey) {
		return errStoreAddMismatch
	}
	if publicKeyIsNil {
		s.publicKey = id.PublicKey()
	}

	updatedIDs, err := s.addTaggedID(id, peerPattern)
	if err != nil {
		s.revert(updatedIDs)
		return err
	}

	if err := s.save(); err != nil {
		s.revert(updatedIDs)
		if publicKeyIsNil {
			s.publicKey = nil
		}
		return saveErr(err)
	}
	return nil
}

func (s *publicIDStore) ForPeer(peer security.PublicID) (security.PublicID, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	var matchingIDs []security.PublicID
	for id, peerPatterns := range s.state.Store {
		for _, peerPattern := range peerPatterns {
			if peerPattern.MatchedBy(peer.Names()...) {
				matchingIDs = append(matchingIDs, id)
				break
			}
		}
	}
	id, err := NewSetPublicID(matchingIDs...)
	if err != nil {
		return nil, errCombine(err)
	}
	if id == nil {
		return nil, errNoMatchingIDs
	}
	return id, nil
}

func (s *publicIDStore) DefaultPublicID() (security.PublicID, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	var matchingIDs []security.PublicID
	for id, _ := range s.state.Store {
		if s.state.DefaultPattern.MatchedBy(id.Names()...) {
			matchingIDs = append(matchingIDs, id)
		}
	}
	id, err := NewSetPublicID(matchingIDs...)
	if err != nil {
		return nil, errCombine(err)
	}
	if id == nil {
		return nil, errNoMatchingIDs
	}
	return id, nil
}

func (s *publicIDStore) SetDefaultBlessingPattern(pattern security.BlessingPattern) error {
	if err := wire.ValidateBlessingPattern(pattern); err != nil {
		return err
	}
	s.mu.Lock()
	defer s.mu.Unlock()

	oldPattern := s.state.DefaultPattern
	s.state.DefaultPattern = pattern

	if err := s.save(); err != nil {
		s.state.DefaultPattern = oldPattern
		return saveErr(err)
	}
	return nil
}

func (s *publicIDStore) save() error {
	if s.params == nil {
		return nil
	}

	// Save the state to temporary data and signature files, and then move
	// those files to the actually data and signature file. This reduces the
	// risk of loosing all saved data on disk in the event of a Write failure.
	dataPath := path.Join(s.params.Dir, dataFile)
	tempDataPath := dataPath + "_tmp"
	sigPath := path.Join(s.params.Dir, signatureFile)
	tempSigPath := sigPath + "_tmp"

	data, err := os.OpenFile(tempDataPath, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return err
	}
	defer os.Remove(tempDataPath)
	sig, err := os.OpenFile(tempSigPath, os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		return err
	}
	defer os.Remove(tempSigPath)

	swc, err := serialization.NewSigningWriteCloser(data, sig, s.params.Signer, nil)
	if err != nil {
		return err
	}
	if err := vom.NewEncoder(swc).Encode(s.state); err != nil {
		defer swc.Close()
		return err
	}
	if err := swc.Close(); err != nil {
		return err
	}

	if err := os.Rename(tempDataPath, dataPath); err != nil {
		return err
	}
	return os.Rename(tempSigPath, sigPath)
}

func (s *publicIDStore) String() string {
	return fmt.Sprintf("{state: %v, params: %v}", s.state, s.params)
}

// PublicIDStoreParams specifies persistent storage where a PublicIDStore can be
// saved and loaded.
type PublicIDStoreParams struct {
	// Dir specifies a path to a directory in which a serialized PublicIDStore
	// can be saved and loaded.
	Dir string
	// Signer provides a mechanism to sign and verify the serialized bytes.
	Signer security.Signer
}

// NewPublicIDStore returns a security.PublicIDStore based on params.
// * If params is nil, a new store with an empty set of PublicIDs and the default
//   pattern "*" (matched by all PublicIDs) is returned. The store only lives in
//   memory and is never persisted.
// * If params is non-nil, then a store obtained from the serialized data present
//   in params.Dir is returned if the data exists, or else a new store with an
//   empty set of PublicIDs and the default pattern "*" is returned. Any subsequent
//   modifications to the returned store are always signed (using params.Signer)
//   and persisted in params.Dir.
func NewPublicIDStore(params *PublicIDStoreParams) (security.PublicIDStore, error) {
	store := &publicIDStore{
		state:  persistentState{make(taggedIDStore), security.AllPrincipals},
		params: params,
	}
	if store.params == nil {
		return store, nil
	}

	data, dataErr := os.Open(path.Join(store.params.Dir, dataFile))
	defer data.Close()
	sig, sigErr := os.Open(path.Join(store.params.Dir, signatureFile))
	defer sig.Close()

	switch {
	case os.IsNotExist(dataErr) && os.IsNotExist(sigErr):
		// No params exists, returning an empty PublicIDStore.
		return store, nil
	case dataErr != nil:
		return nil, dataErr
	case sigErr != nil:
		return nil, sigErr
	}

	vr, err := serialization.NewVerifyingReader(data, sig, store.params.Signer.PublicKey())
	if err != nil {
		return nil, err
	}
	if vr == nil {
		return nil, errors.New("could not construct VerifyingReader for reading params data")
	}
	if err := vom.NewDecoder(vr).Decode(&store.state); err != nil {
		return nil, err
	}

	for id, _ := range store.state.Store {
		store.publicKey = id.PublicKey()
		break
	}
	return store, nil
}
