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

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"testing"

	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/x/ref/services/agent"
	"v.io/x/ref/services/agent/agentlib"
	"v.io/x/ref/services/agent/internal/ipc"
	"v.io/x/ref/services/agent/internal/server"

	_ "v.io/x/ref/runtime/factories/generic"
)

func createAgent(path string) (agent.KeyManager, func(), error) {
	var defers []func()
	cleanup := func() {
		for _, f := range defers {
			f()
		}
	}
	i := ipc.NewIPC()
	if err := server.ServeKeyManager(i, path, nil); err != nil {
		return nil, cleanup, err
	}
	defers = append(defers, func() { os.RemoveAll(path) })
	sock := filepath.Join(path, "keymgr.sock")
	if err := i.Listen(sock); err != nil {
		return nil, cleanup, err
	}
	defers = append(defers, i.Close)

	m, err := NewKeyManager(sock)
	return m, cleanup, err
}

func TestNoDeviceManager(t *testing.T) {
	agent, cleanup, err := createAgent("")
	defer cleanup()
	if err == nil {
		t.Fatal(err)
	}
	if agent != nil {
		t.Fatal("No agent should be created when key path is empty")
	}
}

func createClient(deviceAgent agent.KeyManager, id [64]byte) (security.Principal, error) {
	dir, err := ioutil.TempDir("", "conn")
	if err != nil {
		return nil, err
	}
	path := filepath.Join(dir, "sock")
	if err := deviceAgent.ServePrincipal(id, path); err != nil {
		return nil, err
	}
	defer os.RemoveAll(dir)
	return agentlib.NewAgentPrincipalX(path)
}

func TestSigning(t *testing.T) {
	path, err := ioutil.TempDir("", "agent")
	if err != nil {
		t.Fatal(err)
	}
	agent, cleanup, err := createAgent(path)
	defer cleanup()
	if err != nil {
		t.Fatal(err)
	}

	id1, err := agent.NewPrincipal(false)
	if err != nil {
		t.Fatal(err)
	}
	id2, err := agent.NewPrincipal(false)
	if err != nil {
		t.Fatal(err)
	}

	dir, err := os.Open(filepath.Join(path, "keys"))
	if err != nil {
		t.Fatal(err)
	}
	files, err := dir.Readdir(-1)
	if err != nil {
		t.Fatal(err)
	}
	if len(files) != 2 {
		t.Errorf("Expected 2 files created, found %d", len(files))
	}

	a, err := createClient(agent, id1)
	if err != nil {
		t.Fatal(err)
	}
	// Serving again should be an error
	if _, err := createClient(agent, id1); verror.ErrorID(err) != verror.ErrExist.ID {
		t.Fatalf("Expected ErrExist, got %v", err)
	}

	b, err := createClient(agent, id2)
	if err != nil {
		t.Fatal(err)
	}
	if reflect.DeepEqual(a.PublicKey(), b.PublicKey()) {
		t.Fatal("Keys should not be equal")
	}
	sig1, err := a.Sign([]byte("foobar"))
	if err != nil {
		t.Fatal(err)
	}
	sig2, err := b.Sign([]byte("foobar"))
	if err != nil {
		t.Fatal(err)
	}
	if !sig1.Verify(a.PublicKey(), []byte("foobar")) {
		t.Errorf("Signature a fails verification")
	}
	if !sig2.Verify(b.PublicKey(), []byte("foobar")) {
		t.Errorf("Signature b fails verification")
	}
	if sig2.Verify(a.PublicKey(), []byte("foobar")) {
		t.Errorf("Signatures should not cross verify")
	}
}

func TestInMemorySigning(t *testing.T) {
	path, err := ioutil.TempDir("", "agent")
	if err != nil {
		t.Fatal(err)
	}
	agent, cleanup, err := createAgent(path)
	defer cleanup()
	if err != nil {
		t.Fatal(err)
	}

	id, err := agent.NewPrincipal(true)
	if err != nil {
		t.Fatal(err)
	}

	dir, err := os.Open(filepath.Join(path, "keys"))
	if err != nil {
		t.Fatal(err)
	}
	files, err := dir.Readdir(-1)
	if err != nil {
		t.Fatal(err)
	}
	if len(files) != 0 {
		t.Errorf("Expected 0 files created, found %d", len(files))
	}

	c, err := createClient(agent, id)
	if err != nil {
		t.Fatal(err)
	}
	sig, err := c.Sign([]byte("foobar"))
	if err != nil {
		t.Fatal(err)
	}
	if !sig.Verify(c.PublicKey(), []byte("foobar")) {
		t.Errorf("Signature a fails verification")
	}
}
