/* Copyright (c) 2020-2022 The Creators of Simphone

   See the file COPYING.LESSER.txt for copying permission.
*/

#ifndef _NETWORK_H_
#define _NETWORK_H_

#include "simtypes.h"

/* convert ip address to ASCII */
char *network_convert_ip (unsigned ip);

/* check for non-internet ip address */
simbool sim_network_check_local (unsigned ip);

/* return ip address of default route interface in host byte-order */
unsigned sim_network_get_default (void);

/* if ip is non-NULL, will set *ip to zero if ipstr is a valid ip address or else to the default route */
unsigned sim_network_parse_ip_default (const char *ipstr, unsigned *ip);

/* convert ASCII ip address to host byte-order binary address */
#define sim_network_parse_ip(ipstr) sim_network_parse_ip_default (ipstr, NULL)

/* convert ASCII host:port to SIMSTRING host and *port */
simtype sim_network_parse_host_port (const char *hostport, int *port);

/* convert ASCII ip:port to host byte-order binary address and *port. can also parse only ip if port is NULL */
unsigned sim_network_parse_ip_port (const char *ipport, int *port);

/* extract ip addresses and port numbers from arrays, up to max length.
   return number of extracted couples or negative on error */
int sim_network_parse_ips_ports (const simtype arrayip, const simtype arrayport, unsigned length,
                                 unsigned *ips, int *ports);

/* send command to SOCKS proxy */
int network_connect_socks_ (simsocket sock, unsigned *ip, int port, const char *host, int command);

/* resolve hostname; if SIM_OK return array of *ips (to be freed by caller).
   sock may be NULL for non-cancellable resolving */
int network_dns_resolve_ (simsocket sock, int seconds, const char *host, int port, simbool dht, simtype *ips);

/* set listening port mapping (delete mapping if port is zero) */
int network_set_port (int port);

/* return external port and *ip if known */
int network_get_port (unsigned *ip);

/* update external ip address if connected */
int network_get_ip (void);

/* check port mapping either now (NETWORK_CMD_START or NETWORK_CMD_RESTART) or periodically (NETWORK_CMD_IP) */
int network_periodic (int cmd);

#define NETWORK_CMD_QUIT (-1)    /* exit uPNP thread */
#define NETWORK_CMD_IP (-2)      /* read external (internet) ip address */
#define NETWORK_CMD_START (-3)   /* discover uPNP devices on the network */
#define NETWORK_CMD_RESTART (-4) /* discover uPNP devices and regenerate SSL keys on failure */
#define NETWORK_CMD_RETRY (-5)   /* second invocation (retry) of NETWORK_CMD_RESTART */

/* start and stop uPNP thread */
int network_init (void);
int network_uninit_ (void);

/* debug logging */
void network_log_flags (const char *module, int level);
void network_log_status (const char *module, int level);

#endif
