package i2p

import (
	"net"
)

// i2p network session
type Session interface {

	// get session name
	Name() string
	// open a new control socket
	// does handshaske
	OpenControlSocket() (net.Conn, error)

	// get printable b32.i2p address
	B32Addr() string

	// implements network.Network
	Addr() net.Addr

	// implements net.PacketConn
	LocalAddr() net.Addr

	// implements network.Network
	ReadFrom([]byte) (int, net.Addr, error)

	// implements network.Network
	WriteTo([]byte, net.Addr) (int, error)

	// implements network.Network
	Accept() (net.Conn, error)

	// implements network.Session
	Lookup(name, port string) (net.Addr, error)

	// lookup an i2p address
	LookupI2P(name string) (Addr, error)

	// implements network.Network
	Dial(n, a string) (net.Conn, error)

	// dial out to a remote destination
	DialI2P(a Addr) (net.Conn, error)

	// open the session, generate keys, start up destination etc
	Open() error

	// close the session
	Close() error
}

// create a new i2p session
func NewSession(name, addr, keyfile string, opts map[string]string) Session {
	return &samSession{
		name:       name,
		addr:       addr,
		minversion: "3.0",
		maxversion: "3.0",
		keys:       NewKeyfile(keyfile),
		opts:       opts,
		lookup:     make(chan *lookupReq, 18),
	}
}
