package frontend

import (
	"net"
	"time"

	"git.hush.is/hush/lightwalletd/zrpc"
	"github.com/pkg/errors"
	ini "gopkg.in/ini.v1"
)

// DefaultRPCTimeout bounds a single JSON-RPC round trip to dragonxd.
//
// Why 120s and not something tighter: the slowest legitimate call this daemon
// makes is `coinsupply`, measured at 48s on first call and 3s afterwards.
// hush_coinsupply walks the block index back to genesis loading each block from
// disk, memoising newcoins/zfunds into the CBlockIndex as it goes, so the first
// call pays for the whole chain and later ones are nearly free. A timeout below
// that first-call cost would turn a slow-but-working call into a hard failure.
// 120s leaves ~2.5x headroom while still bounding a hang that is otherwise
// unbounded -- calls were seen running past five minutes.
const DefaultRPCTimeout = 120 * time.Second

// DefaultRPCMaxConcurrent matches dragonxd's DEFAULT_HTTP_THREADS. Asking for
// more in-flight calls than the node has worker threads only adds queueing.
const DefaultRPCMaxConcurrent = 8

func NewZRPCFromConf(confPath string, timeout time.Duration, maxConcurrent int) (*zrpc.Client, error) {
	cfg, err := ini.Load(confPath)
	if err != nil {
		return nil, errors.Wrap(err, "failed to read config file")
	}

	rpcaddr := cfg.Section("").Key("rpcbind").String()
	rpcport := cfg.Section("").Key("rpcport").String()
	username := cfg.Section("").Key("rpcuser").String()
	password := cfg.Section("").Key("rpcpassword").String()

	return NewZRPCFromCreds(net.JoinHostPort(rpcaddr, rpcport), username, password, timeout, maxConcurrent)
}

func NewZRPCFromCreds(addr, username, password string, timeout time.Duration, maxConcurrent int) (*zrpc.Client, error) {
	// DragonX only supports HTTP POST mode and does not provide TLS by default.
	return zrpc.New(addr, username, password, timeout, maxConcurrent), nil
}
