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

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
	"time"

	"golang.org/x/crypto/nacl/box"
)

// Implements net.Conn. Encrypts messages using keys negotioated via NaCl.
// TODO: blessings
// TODO: discharges and caveats
// TODO: ensuer that all 5 of these are set. Constructor?
// TODO: do I need to check the message size as in box_coipher.Seal?
// TODO: make all these keys not pointers?
type conn struct {
	rawConn   net.Conn
	publicKey *[32]byte
	secretKey *[32]byte
	sharedKey *[32]byte
	binding   []byte
	nonce     [24]byte
	counter   uint64 // Why is this so weirdly handled in advanceNonce?
}

func (c *conn) Read(b []byte) (n int, err error) {
	return 0, nil
}

// TODO: all this casting is gross
func (c *conn) Write(b []byte) (n int, err error) {
	tmp := make([]byte, len(b)+box.Overhead) // TODO: is this enough? Also, why do we need both of tmp and out?
	out := box.SealAfterPrecomputation(tmp, b, c.currentNonce(), c.sharedKey)
	c.advanceNonce()
	bytesCopied, err := io.Copy(c.rawConn, bytes.NewReader(out))
	if err != nil {
		return int(bytesCopied), err
	}
	if bytesCopied != int64(len(out)) {
		errMsg := fmt.Sprintf("Did not write entire message. Expected to write %d bytes but wrote %d.", len(out), bytesCopied)
		return -1, errors.New(errMsg)
	}
	return int(bytesCopied), nil
}

// TODO: cover these up with an interface?
func (c *conn) Close() error {
	return c.rawConn.Close()
}

func (c *conn) LocalAddr() net.Addr {
	return c.rawConn.LocalAddr()
}

func (c *conn) RemoteAddr() net.Addr {
	return c.rawConn.RemoteAddr()
}

func (c *conn) SetDeadline(t time.Time) error {
	return c.rawConn.SetDeadline(t)
}

func (c *conn) SetReadDeadline(t time.Time) error {
	return c.rawConn.SetReadDeadline(t)
}

func (c *conn) SetWriteDeadline(t time.Time) error {
	return c.rawConn.SetWriteDeadline(t)
}

// TODO: should I just collapse current and advance?
func (c *conn) currentNonce() *[24]byte {
	return &c.nonce
}

func (c *conn) advanceNonce() {
	c.counter++
	binary.LittleEndian.PutUint64(c.nonce[:], c.counter)
}
