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

import (
	"bytes"
	"fmt"
	"reflect"
	"testing"

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

	"v.io/x/lib/ibe"
)

func newRoot(name string) *Root {
	master, err := ibe.SetupBB1()
	if err != nil {
		panic(err)
	}
	return NewRoot(name, master)
}

func newPlaintext() []byte {
	return []byte("AThirtyTwoBytePieceOfTextThisIs!")
}

func TestExtract(t *testing.T) {
	ctx, shutdown := context.RootContext()
	defer shutdown()

	googleYoutube := newRoot("google:youtube")

	// googleYoutube shoud not be able to extract a key for the blessing "google".
	if _, err := googleYoutube.Extract(ctx, "google"); err == nil {
		t.Fatal("extraction for google unexpectedly succeeded")
	}

	// googleYoutube should be able to extract keys for the following blessings.
	blessings := []string{"google:youtube", "google:youtube:alice", "google:youtube:bob", "google:youtube:alice:phone"}
	for _, b := range blessings {
		key, err := googleYoutube.Extract(ctx, b)
		if err != nil {
			t.Fatal(err)
		}
		if got := key.Blessing(); got != b {
			t.Fatalf("extracted key is for blessing %v, want key for blessing %v", got, b)
		}
		if got, want := key.Params(), googleYoutube.Params(); !reflect.DeepEqual(got, want) {
			t.Fatalf("extract key is for params %v, want key for params %v", got, want)
		}
	}
	// Every key should be unique.
	key1, _ := googleYoutube.Extract(ctx, "google:youtube:alice")
	key2, _ := googleYoutube.Extract(ctx, "google:youtube:alice")
	if reflect.DeepEqual(key1, key2) {
		t.Fatal("Two Extract operations yielded the same PrivateKey")
	}
}

func TestEncrypt(t *testing.T) {
	ctx, shutdown := context.RootContext()
	defer shutdown()

	var (
		googleYoutube = newRoot("google:youtube")
		google        = newRoot("google")

		encrypter = NewCrypter()
		ptxt      = newPlaintext()
	)

	// empty encrypter should not be able to encrypt for any pattern.
	if _, err := encrypter.Encrypt(ctx, "google:youtube:alice", ptxt); verror.ErrorID(err) != ErrNoParams.ID {
		t.Fatalf("Got error %v, wanted error with ID %v", err, ErrNoParams.ID)
	}

	// add googleYoutube's params to the encrypter.
	if err := encrypter.AddParams(ctx, googleYoutube.Params()); err != nil {
		t.Fatal(err)
	}
	// encrypting for "google:youtube:alice" should now succeed.
	if _, err := encrypter.Encrypt(ctx, "google:youtube:alice", ptxt); err != nil {
		t.Fatal(err)
	}

	// encrypting for pattern "google" should still fail as the encrypter
	// does not have params that are authoritative on all blessings matching
	// the pattern "google" (the googleYoutube params are authoritative on
	// blessings matching "google:youtube").
	if _, err := encrypter.Encrypt(ctx, "google", ptxt); verror.ErrorID(err) != ErrNoParams.ID {
		t.Fatalf("Got error %v, wanted error with ID %v", err, ErrNoParams.ID)
	}
	// add google's params to the encrypter.
	if err := encrypter.AddParams(ctx, google.Params()); err != nil {
		t.Fatal(err)
	}
	// encrypting for "google" should now succeed.
	if _, err := encrypter.Encrypt(ctx, "google", ptxt); err != nil {
		t.Fatal(err)
	}

	// Encryption should succeed for all of the following patterns
	patterns := []security.BlessingPattern{"google", "google:$", "google:alice", "google:bob", "google:bob:phone"}
	for _, p := range patterns {
		if _, err := encrypter.Encrypt(ctx, p, ptxt); err != nil {
			t.Fatal(err)
		}
	}

	// Every ciphertext should be unique.
	ctxt1, _ := encrypter.Encrypt(ctx, "google", ptxt)
	ctxt2, _ := encrypter.Encrypt(ctx, "google", ptxt)
	if reflect.DeepEqual(ctxt1, ctxt2) {
		t.Fatal("Two Encrypt operations yielded the same Ciphertext")
	}
}

func TestDecrypt(t *testing.T) {
	ctx, shutdown := context.RootContext()
	defer shutdown()

	addParams := func(c *Crypter, params Params) {
		if err := c.AddParams(ctx, params); err != nil {
			t.Fatal(err)
		}
	}
	extract := func(r *Root, b string) *PrivateKey {
		key, err := r.Extract(ctx, b)
		if err != nil {
			t.Fatal(err)
		}
		return key
	}
	var (
		// Create two roots for the name "google".
		google1 = newRoot("google")
		google2 = newRoot("google")

		encrypter = NewCrypter()
		ptxt      = newPlaintext()

		googleAlice1 = extract(google1, "google:alice:phone")
		googleAlice2 = extract(google2, "google:alice:tablet:app")
	)

	// Add roots google1 and google2 to the encrypter.
	addParams(encrypter, google1.Params())
	addParams(encrypter, google2.Params())
	// encrypt for the pattern "google:alice"
	ctxt, err := encrypter.Encrypt(ctx, "google:alice", ptxt)
	if err != nil {
		t.Fatal(err)
	}

	// A decrypter without any private key should not be able
	// to decrypt this ciphertext.
	decrypter := NewCrypter()
	if _, err := decrypter.Decrypt(ctx, ctxt); verror.ErrorID(err) != ErrPrivateKeyNotFound.ID {
		t.Fatalf("Got error %v, wanted error with ID %v", err, ErrPrivateKeyNotFound.ID)
	}

	// Add key googleAlice1 to the decrypter.
	if err := decrypter.AddKey(ctx, googleAlice1); err != nil {
		t.Fatal(err)
	}
	// Decryption should now succeed.
	if got, err := decrypter.Decrypt(ctx, ctxt); err != nil {
		t.Fatal(err)
	} else if !bytes.Equal(got, ptxt) {
		t.Fatalf("Got plaintext %v, want %v", got, ptxt)
	}

	// Decryption should have succeeded had the decrypter only contained
	// googleAlice2.
	decrypter = NewCrypter()
	if err := decrypter.AddKey(ctx, googleAlice2); err != nil {
		t.Fatal(err)
	}
	if got, err := decrypter.Decrypt(ctx, ctxt); err != nil {
		t.Fatal(err)
	} else if !bytes.Equal(got, ptxt) {
		t.Fatalf("Got plaintext %v, want %v", got, ptxt)
	}

	// Decryption should fail for ciphertexts encrypted for the following
	// patterns (At this point the decrypter only has a key for the blessing
	// "google:alice:tablet:app" from the root google2).
	patterns := []security.BlessingPattern{"google:alice:$", "google:bob", "google:alice:tablet:$", "google:bob:tablet"}
	for _, p := range patterns {
		ctxt, err := encrypter.Encrypt(ctx, p, ptxt)
		if err != nil {
			t.Fatal(err)
		}
		if _, err := decrypter.Decrypt(ctx, ctxt); verror.ErrorID(err) != ErrPrivateKeyNotFound.ID {
			t.Fatalf("Got error %v, wanted error with ID %v", err, ErrPrivateKeyNotFound.ID)
		}
	}

	// Adding the private key googleAlice2 should have also added
	// google's public params. Thus encrypting for the following
	// patterns should succeed.
	patterns = []security.BlessingPattern{"google", "google:$", "google:alice", "google:bob", "google:bob:phone"}
	for _, p := range patterns {
		if _, err := decrypter.Encrypt(ctx, p, ptxt); err != nil {
			t.Fatal(err)
		}
	}
	// But encrypting for the following patterns should fail.
	patterns = []security.BlessingPattern{"youtube", "youtube:$", "youtube:alice"}
	for _, p := range patterns {
		if _, err := decrypter.Encrypt(ctx, p, ptxt); verror.ErrorID(err) != ErrNoParams.ID {
			t.Fatalf("Got error %v, wanted error with ID %v", err, ErrNoParams.ID)
		}
	}
}

func TestWireCiphertext(t *testing.T) {
	ctx, shutdown := context.RootContext()
	defer shutdown()
	ptxt := newPlaintext()

	encrypt := func(params Params, pattern security.BlessingPattern) *Ciphertext {
		enc := NewCrypter()
		if err := enc.AddParams(ctx, params); err != nil {
			t.Fatal(err)
		}
		ctxt, err := enc.Encrypt(ctx, pattern, ptxt)
		if err != nil {
			t.Fatal(err)
		}
		return ctxt
	}
	decryptAndVerify := func(ctxt *Ciphertext, key *PrivateKey) error {
		dec := NewCrypter()
		if err := dec.AddKey(ctx, key); err != nil {
			return err
		}
		if got, err := dec.Decrypt(ctx, ctxt); err != nil {
			return err
		} else if !bytes.Equal(got, ptxt) {
			return fmt.Errorf("got plaintext %v, want %v", got, ptxt)
		}
		return nil
	}

	var (
		google = newRoot("google")
		params = google.Params()
		key, _ = google.Extract(ctx, "google")
		ctxt   = encrypt(params, "google:$")
	)
	// Verify that the ciphertext 'ctxt' can be decrypted using
	// private key 'key' into the desired plaintext.
	if err := decryptAndVerify(ctxt, key); err != nil {
		t.Fatal(err)
	}

	// Marshal and Unmarshal ciphertext 'ctxt' and verify that decryption
	// with private key 'key' still succeeds.
	var (
		newCtxt  Ciphertext
		wireCtxt WireCiphertext
	)
	ctxt.ToWire(&wireCtxt)
	newCtxt.FromWire(wireCtxt)
	if err := decryptAndVerify(&newCtxt, key); err != nil {
		t.Fatal(err)
	}

	// Marshal and Unmarshal the private key 'key' and verify that decryption
	// of 'ctxt' still succeeds.
	var (
		newKey  PrivateKey
		wireKey WirePrivateKey
	)
	if err := key.ToWire(&wireKey); err != nil {
		t.Fatal(err)
	} else if err = newKey.FromWire(wireKey); err != nil {
		t.Fatal(err)
	}
	if err := decryptAndVerify(ctxt, &newKey); err != nil {
		t.Fatal(err)
	}

	// Marshal and Unmarshal the root params and verify that encryption
	// still results in a ciphertext that can be decrypted with the private
	// key 'key'.
	var (
		newParams  Params
		wireParams WireParams
	)
	if err := params.ToWire(&wireParams); err != nil {
		t.Fatal(err)
	} else if err = newParams.FromWire(wireParams); err != nil {
		t.Fatal(err)
	}
	ctxt = encrypt(newParams, "google:$")
	if err := decryptAndVerify(ctxt, key); err != nil {
		t.Fatal(err)
	}
}
