// 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() [32]byte {
	var m [32]byte
	if n := copy(m[:], []byte("AThirtyTwoBytePieceOfTextThisIs!")); n != len(m) {
		panic(fmt.Errorf("plaintext string must be %d bytes, not %d", len(m), n))
	}
	return m
}

func TextExtract(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)
	}
}
