package networking

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"io"
	"log"
)

type Connection[T any] struct {
	Conn    *tls.Conn
	encoder *json.Encoder
	decoder *json.Decoder
}

func NewConnection[T any](netConn *tls.Conn) Connection[T] {
	return Connection[T]{
		Conn:    netConn,
		encoder: json.NewEncoder(netConn),
		decoder: json.NewDecoder(netConn),
	}
}

func (c Connection[T]) Send(obj T) bool {
    if err := c.encoder.Encode(&obj); err!=nil {
		if err == io.EOF {
			log.Println("Connection closed by peer")
            //Return false as connection not active
			return false
		} else {
			log.Panic(err)
		}
    }
    //Return true as connection active
    return true
}

func (c Connection[T]) Receive() (*T, bool) {
	var obj T
	if err := c.decoder.Decode(&obj); err != nil {
		if err == io.EOF {
			log.Println("Connection closed by peer")
            //Return false as connection not active
			return nil,false 
		} else {
			log.Panic(err)
		}
	}
    //Return true as connection active
	return &obj, true
}

func (c Connection[T]) GetPeerCertificate() *x509.Certificate {
	state := c.Conn.ConnectionState()
	return state.PeerCertificates[0]
}