package security

import (
	"crypto/ecdsa"
	"fmt"
	"os"
	"path"

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

const (
	blessingStoreDataFile = "blessingstore.data"
	blessingStoreSigFile  = "blessingstore.sig"

	blessingRootsDataFile = "blessingroots.data"
	blessingRootsSigFile  = "blessingroots.sig"

	privateKeyFile = "privatekey.pem"
)

// NewPrincipal mints a new private key and generates a principal based on
// this key, storing its BlessingRoots and BlessingStore in memory.
func NewPrincipal() (security.Principal, error) {
	pub, priv, err := NewPrincipalKey()
	if err != nil {
		return nil, err
	}
	return security.CreatePrincipal(security.NewInMemoryECDSASigner(priv), newInMemoryBlessingStore(pub), newInMemoryBlessingRoots())
}

// PrincipalStateSerializer is used to persist BlessingRoots/BlessingStore state for
// a principal with the provided SerializerReaderWriters.
type PrincipalStateSerializer struct {
	BlessingRoots SerializerReaderWriter
	BlessingStore SerializerReaderWriter
}

// NewPrincipalStateSerializer is a convenience function that returns a serializer
// for BlessingStore and BlessingRoots given a directory location. We create the
// directory if it does not already exist.
func NewPrincipalStateSerializer(dir string) (*PrincipalStateSerializer, error) {
	if err := mkDir(dir); err != nil {
		return nil, err
	}
	roots, err := NewFileSerializer(path.Join(dir, blessingRootsDataFile), path.Join(dir, blessingRootsSigFile))
	if err != nil {
		return nil, err
	}
	store, err := NewFileSerializer(path.Join(dir, blessingStoreDataFile), path.Join(dir, blessingStoreSigFile))
	if err != nil {
		return nil, err
	}
	return &PrincipalStateSerializer{
		BlessingRoots: roots,
		BlessingStore: store,
	}, nil
}

// NewPrincipalFromSigner creates a new principal using the provided Signer. If previously
// persisted state is available, we use the serializers to populate BlessingRoots/BlessingStore
// for the Principal. If provided, changes to the state are persisted and committed with the
// same serializers. Otherwise, the state (ie: BlessingStore, BlessingRoots) is kept in memory.
func NewPrincipalFromSigner(signer security.Signer, state *PrincipalStateSerializer) (security.Principal, error) {
	if state == nil {
		return security.CreatePrincipal(signer, newInMemoryBlessingStore(signer.PublicKey()), newInMemoryBlessingRoots())
	}
	serializationSigner, err := security.CreatePrincipal(signer, nil, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create serialization.Signer: %v", err)
	}
	blessingRoots, err := newPersistingBlessingRoots(state.BlessingRoots, serializationSigner)
	if err != nil {
		return nil, fmt.Errorf("failed to load BlessingRoots: %v", err)
	}
	blessingStore, err := newPersistingBlessingStore(state.BlessingStore, serializationSigner)
	if err != nil {
		return nil, fmt.Errorf("failed to load BlessingStore: %v", err)
	}
	return security.CreatePrincipal(signer, blessingStore, blessingRoots)
}

// LoadPersistentPrincipal reads state for a principal (private key, BlessingRoots, BlessingStore)
// from the provided directory 'dir' and commits all state changes to the same directory.
// If private key file does not exist then an error 'err' is returned such that os.IsNotExist(err) is true.
// If private key file exists then 'passphrase' must be correct, otherwise PassphraseErr will be returned.
func LoadPersistentPrincipal(dir string, passphrase []byte) (security.Principal, error) {
	key, err := loadKeyFromDir(dir, passphrase)
	if err != nil {
		return nil, err
	}
	state, err := NewPrincipalStateSerializer(dir)
	if err != nil {
		return nil, err
	}
	return NewPrincipalFromSigner(security.NewInMemoryECDSASigner(key), state)
}

// CreatePersistentPrincipal creates a new principal (private key, BlessingRoots,
// BlessingStore) and commits all state changes to the provided directory.
//
// The generated private key is serialized and saved encrypted if the 'passphrase'
// is non-nil, and unencrypted otherwise.
//
// If the directory has any preexisting principal data, CreatePersistentPrincipal
// will return an error.
//
// The specified directory may not exist, in which case it gets created by this
// function.
func CreatePersistentPrincipal(dir string, passphrase []byte) (principal security.Principal, err error) {
	if err := mkDir(dir); err != nil {
		return nil, err
	}
	key, err := initKey(dir, passphrase)
	if err != nil {
		return nil, fmt.Errorf("failed to initialize private key: %v", err)
	}
	state, err := NewPrincipalStateSerializer(dir)
	if err != nil {
		return nil, err
	}
	return NewPrincipalFromSigner(security.NewInMemoryECDSASigner(key), state)
}

// InitDefaultBlessings uses the provided principal to create a self blessing for name 'name',
// sets it as default on the principal's BlessingStore and adds it as root to the principal's BlessingRoots.
func InitDefaultBlessings(p security.Principal, name string) error {
	blessing, err := p.BlessSelf(name)
	if err != nil {
		return err
	}
	if err := p.BlessingStore().SetDefault(blessing); err != nil {
		return err
	}
	if _, err := p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
		return err
	}
	if err := p.AddToRoots(blessing); err != nil {
		return err
	}
	return nil
}

func mkDir(dir string) error {
	if finfo, err := os.Stat(dir); err == nil {
		if !finfo.IsDir() {
			return fmt.Errorf("%q is not a directory", dir)
		}
	} else if err := os.MkdirAll(dir, 0700); err != nil {
		return fmt.Errorf("failed to create %q: %v", dir, err)
	}
	return nil
}

func loadKeyFromDir(dir string, passphrase []byte) (*ecdsa.PrivateKey, error) {
	keyFile := path.Join(dir, privateKeyFile)
	f, err := os.Open(keyFile)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	key, err := LoadPEMKey(f, passphrase)
	if err != nil {
		return nil, err
	}
	return key.(*ecdsa.PrivateKey), nil
}

func initKey(dir string, passphrase []byte) (*ecdsa.PrivateKey, error) {
	keyFile := path.Join(dir, privateKeyFile)
	f, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600)
	if err != nil {
		return nil, fmt.Errorf("failed to open %q for writing: %v", keyFile, err)
	}
	defer f.Close()
	_, key, err := NewPrincipalKey()
	if err != nil {
		return nil, fmt.Errorf("failed to generate private key: %v", err)
	}
	if err := SavePEMKey(f, key, passphrase); err != nil {
		return nil, fmt.Errorf("failed to save private key to %q: %v", keyFile, err)
	}
	return key, nil
}
