/**
 * Connects to Bitcoin daemon and retrieves information, then writes to cache
 *
 * @param string $from_cache Whether to get the data from cache or not
 *
 * @return array
 */
function getData($from_cache = false)
{
    global $config;
    global $cache_message;
    // If we're getting data from cache, do it
    if ($from_cache === true && is_file($config['cache_file'])) {
        $cache = json_decode(file_get_contents($config['cache_file']), true);
        // Only proceed if the array is a cache - invalid otherwise
        if (is_array($cache)) {
            if ($cache['config_hash'] == md5(json_encode($config))) {
                if (time() < $cache['cache_expiry']) {
                    return $cache;
                }
            } else {
                $cache_message = 'Configuration has changed, cache has been refreshed.';
            }
        }
    }
    // Include EasyBitcoin library and set up connection
    include_once './php/easybitcoin.php';
    $bitcoin = new Bitcoin($config['rpc_user'], $config['rpc_pass'], $config['rpc_host'], $config['rpc_port']);
    // Setup SSL if configured
    if ($config['rpc_ssl'] === true) {
        $bitcoin->setSSL($config['rpc_ssl_ca']);
    }
    // Get info
    $data = $bitcoin->getinfo();
    // Handle errors if they happened
    if (!$data) {
        $return_data['error'] = $bitcoin->error;
        $return_data['status'] = $bitcoin->status;
        writeToCache($return_data);
        return $return_data;
    }
    // Get free disk space
    if ($config['display_free_disk_space'] === true) {
        $data['free_disk_space'] = getFreeDiskSpace();
    }
    if (isset($config['display_ip']) && $config['display_ip'] === true) {
        // Use bitcoind IP
        if ($config['use_bitcoind_ip'] === true) {
            $net_info = $bitcoin->getnetworkinfo();
            $data['node_ip'] = $net_info['localaddresses'][0]['address'];
        } else {
            $data['node_ip'] = $_SERVER['SERVER_ADDR'];
        }
    }
    // Add peer info
    if ($config['display_peer_info'] === true) {
        $data['peers'] = parsePeers($bitcoin->getpeerinfo());
    }
    // Node geolocation
    if ($config['display_ip_location'] === true && $config['display_ip'] === true) {
        $data['ip_location'] = getGeolocation($data['node_ip'], 'all');
    }
    // Bitcoin Daemon uptime
    if ($config['display_bitcoind_uptime'] === true || strcmp(PHP_OS, "Linux") == 0) {
        $data['bitcoind_uptime'] = getProcessUptime($config['bitcoind_process_name']);
    }
    // Get max height from bitnodes.21.co
    if ($config['display_max_height'] === true) {
        $bitnodes_ch = curl_init();
        curl_setopt($bitnodes_ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($bitnodes_ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($bitnodes_ch, CURLOPT_USERAGENT, 'Bitcoin Node Status Page');
        curl_setopt($bitnodes_ch, CURLOPT_URL, "https://bitnodes.21.co/api/v1/snapshots/");
        $exec_result = json_decode(curl_exec($bitnodes_ch), true);
        // Don't close handle if we reuse it
        if ($config['display_bitnodes_info'] !== true) {
            curl_close($bitnodes_ch);
        }
        $data['max_height'] = $exec_result['results'][0]['latest_height'];
        $data['node_height_percent'] = round($data['blocks'] / $data['max_height'] * 100, 1);
    }
    // Get node info from bitnodes.21.co
    if ($config['display_bitnodes_info'] === true) {
        if ($bitnodes_ch === false) {
            $bitnodes_ch = curl_init();
            curl_setopt($bitnodes_ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($bitnodes_ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($bitnodes_ch, CURLOPT_USERAGENT, 'Bitcoin Node Status Page');
        }
        // Get node info
        curl_setopt($bitnodes_ch, CURLOPT_URL, "https://getaddr.bitnodes.21.co/api/v1/nodes/" . $data['node_ip'] . "-8333/");
        $data['bitnodes_info'] = json_decode(curl_exec($bitnodes_ch), true);
        // Get latency info
        curl_setopt($bitnodes_ch, CURLOPT_URL, "https://getaddr.bitnodes.21.co/api/v1/nodes/" . $data['node_ip'] . "-8333/latency/");
        $latency = json_decode(curl_exec($bitnodes_ch), true);
        $data['bitnodes_info']['latest_latency'] = $latency['daily_latency'][0];
    }
    // Get chart data
    if ($config['display_chart'] === true & is_file($config['stats_file'])) {
        $data['chart'] = json_decode(file_get_contents($config['stats_file']), true);
    }
    writeToCache($data);
    return $data;
}