// 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"
	_ "io/ioutil"
	"log"
	"net"
	_ "runtime/debug"
	"sync"
	"time"

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

const doEncrypt = true

// 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?
// TODO: should I have locks here?
// TODO: what's all this salsa stuff?
type conn struct {
	rawConn   net.Conn
	publicKey *[32]byte
	secretKey *[32]byte
	sharedKey *[32]byte
	binding   []byte
	nonce     [24]byte // TODO: do I need a second nonce? Does this need to be random?
	counter   uint64   // Why is this so weirdly handled in advanceNonce?
	mu        sync.Mutex
}

// TODO: what if bytesRead < 3? = 3?
func (c *conn) Read(b []byte) (n int, err error) {
	// c.mu.Lock()
	// defer c.mu.Unlock()

	if !doEncrypt {
		log.Printf("Beginning to Read.\n")
		frame := [3]byte{}
		frameCopied, err := c.rawConn.Read(frame[:])
		if frameCopied != 3 {
			return frameCopied, errors.New("Did not copy 3 frame bytes.")
		}
		msgSize := read3ByteUint(frame)

		resBuf := make([]byte, msgSize)
		bytesRead, err := c.rawConn.Read(resBuf)
		if err != nil {
			log.Fatal(err)
		}
		copy(b, resBuf)
		log.Printf("Read %d bytes: %v\n", bytesRead, resBuf)
		log.Printf("Succeeded in reading.\n\n")
		return bytesRead, nil
		// return len(b), nil
	}

	log.Printf("Beginning to Read.\n")

	frame := [3]byte{}
	frameCopied, err := c.rawConn.Read(frame[:])
	if frameCopied != 3 {
		return frameCopied, errors.New("Did not copy 3 frame bytes.")
	}
	msgSize := read3ByteUint(frame)

	resBuf := make([]byte, msgSize) // TODO better (dynamic) size or way of reading?
	bytesRead, err := c.rawConn.Read(resBuf)
	// log.Printf("Read %d bytes: %v\n", bytesRead, resBuf)
	if err != nil {
		// log.Printf("Failed to read.\n")
		log.Fatal(err)
		return bytesRead, err
	}

	// tmp := make([]byte, 0, bytesRead-box.Overhead) // TODO: is this enough? Also, why do we need both of tmp and out?
	out, ok := box.OpenAfterPrecomputation(nil, resBuf, c.currentNonce(), c.sharedKey)
	log.Printf("%d bytes after opening: %v\n", len(out), out)
	// log.Printf("%d bytes after opening: %v\n", len(out), string(out))
	c.advanceNonce() // TODO: defer? Is there harm in advancing often than necessary (i.e. on error)?
	if !ok {
		// log.Printf("Failed to decrypt.\n")
		//log.Fatal(err)
		return 0, err
	}
	copy(b, out)
	// should we return bytesRead or len(b)?
	// log.Printf("cap(b): %d, len(b) %d, \ncap(out): %d, len(out): %d\n", cap(b), len(b), cap(out), len(out))
	log.Printf("Succeeded in reading.\n\n")
	// return bytesRead, nil
	// return len(b), nil
	return len(out), nil
}

// TODO: all this casting is gross
func (c *conn) Write(b []byte) (n int, err error) {
	// log.Printf("Write called:\n%v\n", string(debug.Stack()))
	// c.mu.Lock()
	// defer c.mu.Unlock()

	if !doEncrypt {
		log.Printf("Beginning to write.\n")
		tmp := make([]byte, 3)
		err = write3ByteUint(tmp, len(b))
		if err != nil {
			return 0, err
		}
		bytesCopied, err := io.Copy(c.rawConn, bytes.NewReader(tmp))
		if err != nil {
			log.Fatal(err)
		}
		bytesCopied, err = io.Copy(c.rawConn, bytes.NewReader(b))
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("Wrote %d bytes: %v\n", bytesCopied, b)
		log.Printf("Succeeded in writing!\n\n")
		// // return int(bytesCopied), nil
		return len(b), nil
	}

	log.Printf("Beginning to write.\n")
	log.Printf("%d bytes before sealing: %v\n", len(b), b)
	tmp := make([]byte, 3, 3+len(b)+box.Overhead) // TODO: is this enough? Also, why do we need both of tmp and out?
	err = write3ByteUint(tmp[:3], len(b)+box.Overhead)
	if err != nil {
		return 0, err
	}
	out := box.SealAfterPrecomputation(tmp, b, c.currentNonce(), c.sharedKey)
	// log.Printf("tmp: %v", tmp)
	// log.Printf("out: %v", out)
	c.advanceNonce()
	bytesCopied, err := io.Copy(c.rawConn, bytes.NewReader(out))
	// log.Printf("Wrote %d bytes.\n", bytesCopied)
	if err != nil {
		log.Printf("Failed to copy to rawConn.\n")
		log.Fatal(err)
		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)
		log.Printf("Did not write entire message. Expected to write %d bytes but wrote %d.", len(out), bytesCopied)
		log.Printf("Failed to write.\n")
		log.Fatal(err)
		return int(bytesCopied), errors.New(errMsg)
	}
	// log.Printf("cap(b): %d, len(b) %d, cap(out): %d, len(out): %d\n", cap(b), len(b), cap(out), len(out))
	log.Printf("Succeeded in writing!\n\n")
	// return int(bytesCopied), nil
	return len(b), nil
}

// TODO: understand this stuff
const maxPacketSize = 0xffffff

func write3ByteUint(dst []byte, n int) error {
	if n > maxPacketSize || n < 0 {
		// return NewErrLargerThan3ByteUInt(nil)
		return errors.New("TOOO BIG")
	}
	n = maxPacketSize - n
	dst[0] = byte((n & 0xff0000) >> 16)
	dst[1] = byte((n & 0x00ff00) >> 8)
	dst[2] = byte(n & 0x0000ff)
	return nil
}

func read3ByteUint(src [3]byte) int {
	return maxPacketSize - (int(src[0])<<16 | int(src[1])<<8 | int(src[2]))
}

// TODO: cover these up with an interface?
// TODO: remove all these useless mutex locks and unlocks
func (c *conn) Close() error {
	// c.mu.Lock()
	// defer c.mu.Unlock()
	log.Printf("SOMEONE IS CLOSING THE CONNECTION\n")
	return c.rawConn.Close()
}

func (c *conn) LocalAddr() net.Addr {
	// c.mu.Lock()
	// defer c.mu.Unlock()
	return c.rawConn.LocalAddr()
}

func (c *conn) RemoteAddr() net.Addr {
	// c.mu.Lock()
	// defer c.mu.Unlock()
	return c.rawConn.RemoteAddr()
}

func (c *conn) SetDeadline(t time.Time) error {
	// c.mu.Lock()
	// defer c.mu.Unlock()
	return c.rawConn.SetDeadline(t)
}

func (c *conn) SetReadDeadline(t time.Time) error {
	// c.mu.Lock()
	// defer c.mu.Unlock()
	return c.rawConn.SetReadDeadline(t)
}

func (c *conn) SetWriteDeadline(t time.Time) error {
	// c.mu.Lock()
	// defer c.mu.Unlock()
	return c.rawConn.SetWriteDeadline(t)
}

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

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