// 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"
)

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 PassphraseError if the passphrase is nil.
	if _, err = LoadPersistentPrincipal(dir, nil); err != PassphraseErr {
		t.Errorf("encrypted LoadPersistentPrincipal with nil passphrase should return PassphraseErr: %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)
			}
		}
	}
}
