// Copyright 2016 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 grpc

// TODO(krakauer): better name

import (
	_ "bufio"
	_ "bytes"
	"crypto/rand"
	_ "encoding/binary"
	_ "errors"
	"fmt"
	_ "io"
	"log"
	"net"
	"time"

	"github.com/golang/protobuf/proto"
	"golang.org/x/crypto/nacl/box"
	"google.golang.org/grpc/credentials"

	"v.io/x/ref/runtime/internal/flow/conn/grpc/handshake"
	"v.io/x/ref/runtime/internal/rpc/version"
)

const (
	// Just for the sake of stubbing. When succeed is true, we pass back the same net.Conn we got in.
	// It is not encrypted or authenticated.
	succeed    = false
	defaultMtu = 1 << 16
)

// This package provides a set of methods that can be exposed to non-Vanadium RPC systems (e.g.
// gRPC) so that they can utilize Vanadium's authentication (i.e. mutual authentication) and
// authorization (i.e. blessings) capabilities.
//
// This package is explicitly aimed at GRPC for now. See package
// "google.golang.org/grpc/credentials" for more information.

// TODO(krakauer):
// - We'll ignoring blessings at first. Once mutual auth works without it, we can add blessing support.
// - We'll ignore caveats and discharges at first.
// - Use timeouts. See net package docs.
// - When is it my responsibility to close a net.Conn?

type GRPCInfo struct{}

func (GRPCInfo) AuthType() string {
	return "vanadium"
}

// 1 - Send client's public key
// 2 - Get server's public key
// 3 - Compute shared key
// 4 - Compute channel bindings
// If everything checks out at this point, consider the the connection authenticated and return a
// net.Conn that encrypts messages as they are written.
//
// Later:
// 5 - Blessing support
// 6 - Caveat and discharge support.
func ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (net.Conn, credentials.AuthInfo, error) {
	log.Printf("In ClientHandshake.\n")
	return setupSharedSecrets(rawConn, true)
}

// 1 - Send the server's public key
// 2 - Get the client's public key
// 3 - Compute shared key
// 4 - Compute channel bindings
// If everything checks out at this point, consider the the connection authenticated and return a
// net.Conn that encrypts messages as they are written.
//
// Later:
// 5 - Blessing support
// 6 - Caveat and discharge support
func ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
	log.Printf("In ServerHandshake.\n")
	return setupSharedSecrets(rawConn, true)
}

// Generates the shared key and channel bindings for both the server and client handshakes.
func setupSharedSecrets(rawConn net.Conn, doprint bool) (net.Conn, credentials.AuthInfo, error) {
	pk, sk, err := box.GenerateKey(rand.Reader)
	setupReq := &handshake.Setup{
		// Versions are typedefed uint32s.
		MinVersion:        uint32(version.Supported.Min),
		MaxVersion:        uint32(version.Supported.Max),
		PeerNaclPublicKey: pk[:],
		Mtu:               defaultMtu,
	}
	if doprint {
		log.Printf("setupReq: %v", setupReq)
		log.Printf("pk: %v", pk)
	}
	// Now we have to send this message to the server... do we just send it over rawConn while using box?

	// if proto.Size(setupReq) < box.Overhead {
	// 	return nil, nil, errors.New("Message too short") // TODO: what's this check for? It's in box_cipher.go.
	// }

	// There's nothing to seal with with 1st time. We just send our public key as plaintext.
	// First we have to serialize the setup message.
	setupReqData, err := proto.Marshal(setupReq)
	rawConn.Write(setupReqData)

	// Wait until we have our entire reponse.
	log.Printf("Going to wait on Copy.\n")
	// resBuf := bytes.Buffer{}
	// io.Copy(&resBuf, rawConn)
	resBuf := make([]byte, 4096) // TODO better (dynamic) size or way of reading?
	bytesRead, err := rawConn.Read(resBuf)
	if err != nil {
		return nil, nil, err
	}
	log.Printf("Done waiting on Copy.\n")
	log.Printf("Received %d bytes.\n", bytesRead)

	setupRes := &handshake.Setup{}
	// err = proto.Unmarshal(resBuf.Bytes(), setupRes)
	err = proto.Unmarshal(resBuf[:bytesRead], setupRes)
	if err != nil {
		if doprint {
			log.Printf("Failed to unmarshal proto.\n")
			log.Printf("resBuf: %v", resBuf)
		}
		return nil, nil, err
	}

	// TODO: negotiate stuff with the remote (version, mtu, etc.). For now, we are using identical
	// protos, so get this working after.
	var sharedKey [32]byte
	// var peerPublicKey = make([]byte, 32) // TODO does this need both?
	// binary.LittleEndian.PutUint32(peerPublicKey, setupRes.PeerNaclPublicKey)
	// var peerPublicKeyArr [32]byte
	// copy(peerPublicKeyArr[:], peerPublicKey)
	var peerPublicKeyArr [32]byte
	copy(peerPublicKeyArr[:], setupRes.PeerNaclPublicKey)
	box.Precompute(&sharedKey, &peerPublicKeyArr, sk)
	if doprint {
		log.Printf("setupRes: %v", setupRes)
		// log.Printf("peerPublicKeyArr: %v", peerPublicKeyArr)
		log.Printf("sharedKey: %v\n", sharedKey)
	}

	// TODO: maybe this should use a constructor. Also, we can just read the keys directly into this.
	// Declare this at the beginning.
	secureConn := &conn{
		rawConn:   rawConn,
		publicKey: pk,
		secretKey: sk,
		sharedKey: &sharedKey,
		// binding: /* TODO */,
	}

	log.Printf("secureConn: %#v\n", secureConn)

	return secureConn, GRPCInfo{}, nil
}

func SecurityProtocol() string {
	return "vanadium"
}

// Returns the latest version supported.
func SecurityVersion() string {
	return fmt.Sprint(version.Supported.Max)
}
