// 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, false)
}

// 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) {
	// TODO sk
	// TODO a lot
	pk, _, err := box.GenerateKey(rand.Reader)
	// We know that pk is 32 bits, so it's safe to downcast to uint32. TODO make this a helper
	pk64, err := binary.ReadUvarint(bufio.NewReader(bytes.NewReader(pk[:])))
	if err != nil {
		return nil, nil, err
	}

	setupReq := &handshake.Setup{
		// Versions are typedefed uint32s.
		MinVersion:        uint32(version.Supported.Min),
		MaxVersion:        uint32(version.Supported.Max),
		PeerNaclPublicKey: uint32(pk64),
		Mtu:               defaultMtu,
	}
	if doprint {
		log.Printf("setupReq: %v", setupReq)
	}
	// 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
	}
	if doprint {
		log.Printf("setupRes: %v", setupRes)
	}
	// TODO: negotiate stuff with the remote (version, mtu, etc.). For now, we are using identical
	// protos, so get this working after.

	// TODO: wrong, just getting this to compile
	return rawConn, GRPCInfo{}, nil
}

func SecurityProtocol() string {
	return "vanadium"
}

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