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

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"io/ioutil"
	"os"
	"path"
	"reflect"
	"testing"

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

func TestLoadPersistentPrincipal(t *testing.T) {
	// If the directory does not exist want os.IsNotExists.
	_, err := LoadPersistentPrincipal("/tmp/fake/path/", nil)
	if !os.IsNotExist(err) {
		t.Errorf("invalid path should return does not exist error, instead got %v", err)
	}
	// If the key file exists and is unencrypted we should succeed.
	dir := generatePEMFile(nil)
	if _, err = LoadPersistentPrincipal(dir, nil); err != nil {
		t.Errorf("unencrypted LoadPersistentPrincipal should have succeeded: %v", err)
	}
	os.RemoveAll(dir)

	// If the private key file exists and is encrypted we should succeed with correct passphrase.
	passphrase := []byte("passphrase")
	incorrect_passphrase := []byte("incorrect_passphrase")
	dir = generatePEMFile(passphrase)
	if _, err = LoadPersistentPrincipal(dir, passphrase); err != nil {
		t.Errorf("encrypted LoadPersistentPrincipal should have succeeded: %v", err)
	}
	// and fail with an incorrect passphrase.
	if _, err = LoadPersistentPrincipal(dir, incorrect_passphrase); err == nil {
		t.Errorf("encrypted LoadPersistentPrincipal with incorrect passphrase should fail")
	}
	// and return ErrBadPassphrase if the passphrase is nil.
	if _, err = LoadPersistentPrincipal(dir, nil); verror.ErrorID(err) != ErrBadPassphrase.ID {
		t.Errorf("encrypted LoadPersistentPrincipal with nil passphrase should return ErrBadPassphrase: %v", err)
	}
	os.RemoveAll(dir)
}

func TestCreatePersistentPrincipal(t *testing.T) {
	tests := []struct {
		Message, Passphrase []byte
	}{
		{[]byte("unencrypted"), nil},
		{[]byte("encrypted"), []byte("passphrase")},
	}
	for _, test := range tests {
		testCreatePersistentPrincipal(t, test.Message, test.Passphrase)
	}
}

func testCreatePersistentPrincipal(t *testing.T, message, passphrase []byte) {
	// Persistence of the BlessingRoots and BlessingStore objects is
	// tested in other files. Here just test the persistence of the key.
	dir, err := ioutil.TempDir("", "TestCreatePersistentPrincipal")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	p, err := CreatePersistentPrincipal(dir, passphrase)
	if err != nil {
		t.Fatal(err)
	}
	_, err = CreatePersistentPrincipal(dir, passphrase)
	if err == nil {
		t.Error("CreatePersistentPrincipal passed unexpectedly")
	}

	sig, err := p.Sign(message)
	if err != nil {
		t.Fatal(err)
	}

	p2, err := LoadPersistentPrincipal(dir, passphrase)
	if err != nil {
		t.Fatalf("%s failed: %v", message, err)
	}
	if !sig.Verify(p2.PublicKey(), message) {
		t.Errorf("%s failed: p.PublicKey=%v, p2.PublicKey=%v", message, p.PublicKey(), p2.PublicKey())
	}
}

func generatePEMFile(passphrase []byte) (dir string) {
	dir, err := ioutil.TempDir("", "TestLoadPersistentPrincipal")
	if err != nil {
		panic(err)
	}
	key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		panic(err)
	}
	f, err := os.Create(path.Join(dir, privateKeyFile))
	if err != nil {
		panic(err)
	}
	defer f.Close()
	if err = SavePEMKey(f, key, passphrase); err != nil {
		panic(err)
	}
	return dir
}

func TestPrincipalBlessingsByName(t *testing.T) {
	var p1, p2, p3 security.Principal
	var err error

	if p1, err = NewPrincipal(); err != nil {
		t.Fatal(err)
	}
	if p2, err = NewPrincipal(); err != nil {
		t.Fatal(err)
	}
	alice, err := p1.BlessSelf("alice")
	if err != nil {
		t.Fatal(err)
	}
	p2.AddToRoots(alice)
	var aliceworkfriend, alicegymfriend, aliceworkboss security.Blessings

	if aliceworkfriend, err = p1.Bless(p2.PublicKey(), alice, "work/friend", security.UnconstrainedUse()); err != nil {
		t.Errorf("Bless(work/friend) failed: %v", err)
	}
	p2.BlessingStore().Set(aliceworkfriend, "alice/work/friend")
	if alicegymfriend, err = p1.Bless(p2.PublicKey(), alice, "gym/friend", security.UnconstrainedUse()); err != nil {
		t.Errorf("Bless(gym/friend) failed: %v", err)
	}
	p2.BlessingStore().Set(alicegymfriend, "alice/gym/friend")
	if aliceworkboss, err = p1.Bless(p2.PublicKey(), alice, "work/boss", security.UnconstrainedUse()); err != nil {
		t.Errorf("Bless(work/friend) failed: %v", err)
	}
	p2.BlessingStore().Set(aliceworkboss, "alice/work/boss")

	// Blessing from an untrusted principal that should never be returned
	if p3, err = NewPrincipal(); err != nil {
		t.Fatal(err)
	}
	fake, err := p3.BlessSelf("alice")
	if err != nil {
		t.Fatal(err)
	}
	fakefriend, err := p3.Bless(p2.PublicKey(), fake, "work/friend", security.UnconstrainedUse())
	if err != nil {
		t.Errorf("Bless(work/friend) failed: %v", err)
	}
	_, err = p2.BlessingStore().Set(fakefriend, "fake/work/friend")

	tests := []struct {
		matched []security.Blessings
		pattern security.BlessingPattern
	}{
		{
			matched: []security.Blessings{aliceworkfriend, aliceworkboss},
			pattern: "alice/work",
		},
		{
			matched: []security.Blessings{aliceworkfriend},
			pattern: "alice/work/friend",
		},
		{
			matched: []security.Blessings{alicegymfriend},
			pattern: "alice/gym/friend",
		},
		{
			matched: []security.Blessings{aliceworkfriend, alicegymfriend, aliceworkboss},
			pattern: "alice",
		},
		{
			matched: []security.Blessings{aliceworkfriend, alicegymfriend, aliceworkboss},
			pattern: security.AllPrincipals,
		},
		{
			matched: nil,
			pattern: "alice/school",
		},
	}

	for _, test := range tests {
		matched := p2.BlessingsByName(test.pattern)
		if len(matched) != len(test.matched) {
			t.Errorf("BlessingsByName(%s) did not return expected number of matches wanted:%d got:%d", test.pattern, len(test.matched), len(matched))
		}
		for _, m := range matched {
			found := false
			for _, tm := range test.matched {
				if reflect.DeepEqual(m, tm) {
					found = true
					break
				}
			}
			if !found {
				t.Errorf("Invalid blessing was returned as a match:%v for pattern:%s", m, test.pattern)
			}
		}
	}
}
