package connectivity

import (
	"net"
)

// Error captures various common ricochet errors
type Error string

func (e Error) Error() string { return string(e) }

const (
	// CannotResolveLocalTCPAddressError is thrown when a local ricochet connection has the wrong format.
	CannotResolveLocalTCPAddressError = Error("CannotResolveLocalTCPAddressError")
	// CannotDialLocalTCPAddressError is thrown when a connection to a local ricochet address fails.
	CannotDialLocalTCPAddressError = Error("CannotDialLocalTCPAddressError")
)

// PrivateKey represents a private key using an unspecified algorithm.
type PrivateKey interface{}

// ListenService is an address that was opened with Listen() and can Accept() new connections
type ListenService interface {
	// AddressFull is the full network address, ex: rsjeuxzlexy4fvo75vrdtj37nrvlmvbw57n5mhypcjpzv3xkka3l4yyd.onion:9878
	AddressFull() string

	Accept() (net.Conn, error)
	Close()
}

// ACN is Anonymous Communication Network implementation wrapper that supports Open for new connections and Listen to accept connections
type ACN interface {
	// GetBootstrapStatus returns an int 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
	//  On Network down it returns -1
	//  On ACN error state it returns -2
	GetBootstrapStatus() (int, string)
	// WaitTillBootstrapped Blocks until underlying network is bootstrapped
	WaitTillBootstrapped() error
	// Sets the callback function to be called when ACN status changes
	SetStatusCallback(callback func(int, string))

	GetStatusCallback() func(int, string)

	// Sets the callback function to be called when ACN reboots to emit the version
	SetVersionCallback(callback func(string))

	GetVersionCallback() func(string)

	// Restarts the underlying connection
	Restart()

	// Open takes a hostname and returns a net.conn to the derived endpoint
	// Open allows a client to resolve various hostnames to connections
	Open(hostname string) (net.Conn, string, error)

	// Listen takes a private key and a port and returns a ListenService for it
	Listen(identity PrivateKey, port int) (ListenService, error)

	// Get PID
	GetPID() (int, error)

	// GetVersion returns a string of what the ACN returns when asked for a version
	GetVersion() string

	GetInfo(onion string) (map[string]string, error)

	Close()
}
