// 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 (
	"fmt"
	"io/ioutil"
	"os"
	"reflect"
	"sort"
	"testing"

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

type rootsTester [4][]byte

func newRootsTester() *rootsTester {
	var tester rootsTester
	for idx := range tester {
		key, _, err := NewPrincipalKey()
		if err != nil {
			panic(err)
		}
		keybytes, err := key.MarshalBinary()
		if err != nil {
			panic(err)
		}
		tester[idx] = keybytes
	}
	return &tester
}

func (t *rootsTester) add(br security.BlessingRoots) error {
	if err := br.Add(t[0], security.AllPrincipals); err == nil {
		return fmt.Errorf("Add( , %v) succeeded, expected it to fail", security.AllPrincipals)
	}
	testdata := []struct {
		root    []byte
		pattern security.BlessingPattern
	}{
		{t[0], "vanadium"},
		{t[1], "google:foo"},
		{t[2], "google:foo"},
		{t[0], "google:$"},
	}
	for _, d := range testdata {
		if err := br.Add(d.root, d.pattern); err != nil {
			return fmt.Errorf("Add(%v, %q) failed: %s", d.root, d.pattern, err)
		}
	}
	return nil
}

func (t *rootsTester) testRecognized(br security.BlessingRoots) error {
	testdata := []struct {
		root          []byte
		recognized    []string
		notRecognized []string
	}{
		{
			root:          t[0],
			recognized:    []string{"vanadium", "vanadium:foo", "vanadium:foo:bar", "google"},
			notRecognized: []string{"google:foo", "foo", "foo:bar"},
		},
		{
			root:          t[1],
			recognized:    []string{"google:foo", "google:foo:bar"},
			notRecognized: []string{"google", "google:bar", "vanadium", "vanadium:foo", "foo", "foo:bar"},
		},
		{
			root:          t[2],
			recognized:    []string{"google:foo", "google:foo:bar"},
			notRecognized: []string{"google", "google:bar", "vanadium", "vanadium:foo", "foo", "foo:bar"},
		},
		{
			root:          t[3],
			recognized:    []string{},
			notRecognized: []string{"vanadium", "vanadium:foo", "vanadium:bar", "google", "google:foo", "google:bar", "foo", "foo:bar"},
		},
	}
	for _, d := range testdata {
		for _, b := range d.recognized {
			if err := br.Recognized(d.root, b); err != nil {
				return fmt.Errorf("Recognized(%v, %q): got: %v, want nil", d.root, b, err)
			}
		}
		for _, b := range d.notRecognized {
			if err, want := br.Recognized(d.root, b), security.ErrUnrecognizedRoot.ID; verror.ErrorID(err) != want {
				return fmt.Errorf("Recognized(%v, %q): got %v(errorid=%v), want errorid=%v", d.root, b, err, verror.ErrorID(err), want)
			}
		}
	}
	return nil
}

type pubKeySorter []security.PublicKey

func (s pubKeySorter) Len() int           { return len(s) }
func (s pubKeySorter) Less(i, j int) bool { return s[i].String() < s[j].String() }
func (s pubKeySorter) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func (t *rootsTester) testDump(br security.BlessingRoots) error {
	object := func(data []byte) security.PublicKey {
		ret, err := security.UnmarshalPublicKey(data)
		if err != nil {
			panic(err)
		}
		return ret
	}
	want := map[security.BlessingPattern][]security.PublicKey{
		"google:foo": []security.PublicKey{object(t[1]), object(t[2])},
		"google:$":   []security.PublicKey{object(t[0])},
		"vanadium":   []security.PublicKey{object(t[0])},
	}
	got := br.Dump()
	sort.Sort(pubKeySorter(want["google:foo"]))
	sort.Sort(pubKeySorter(got["google:foo"]))
	if !reflect.DeepEqual(got, want) {
		return fmt.Errorf("Dump(): got %v, want %v", got, want)
	}
	return nil
}

func TestBlessingRoots(t *testing.T) {
	p, err := NewPrincipal()
	if err != nil {
		t.Fatal(err)
	}
	tester := newRootsTester()
	if err := tester.add(p.Roots()); err != nil {
		t.Fatal(err)
	}
	if err := tester.testRecognized(p.Roots()); err != nil {
		t.Fatal(err)
	}
	if err := tester.testDump(p.Roots()); err != nil {
		t.Fatal(err)
	}
}

func TestBlessingRootsPersistence(t *testing.T) {
	dir, err := ioutil.TempDir("", "TestBlessingRootsPersistence")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)
	tester := newRootsTester()
	p, err := CreatePersistentPrincipal(dir, nil)
	if err != nil {
		t.Fatal(err)
	}
	if err := tester.add(p.Roots()); err != nil {
		t.Error(err)
	}
	if err := tester.testRecognized(p.Roots()); err != nil {
		t.Error(err)
	}
	if err := tester.testDump(p.Roots()); err != nil {
		t.Error(err)
	}
	// Recreate the principal (and thus BlessingRoots)
	p2, err := LoadPersistentPrincipal(dir, nil)
	if err != nil {
		t.Fatal(err)
	}
	if err := tester.testRecognized(p2.Roots()); err != nil {
		t.Error(err)
	}
	if err := tester.testDump(p2.Roots()); err != nil {
		t.Error(err)
	}
}
