/** @note How to compile:
$BUILDROOT_DIR/build_arm/staging_dir/usr/bin/arm-linux-uclibc-g++ test.cpp
 -o test
 -I$BUILDROOT_DIR/build_arm/staging_dir/usr/include/
 -L$BUILDROOT_DIR/build_arm/staging_dir/usr/lib
 -lcurl
**/
#include <iostream>
#include <string>
#include <sys/stat.h>

#include "curl/curl.h"

using namespace std;

bool DownloadFile(std::string const& url, std::string const& destFilePath)
{
    cout << "Starting download of file \"" << url << "\", destination file path is: \"" << destFilePath << "\"" << endl;

    FILE*       pFile           = fopen(destFilePath.c_str(), "ab+");
    CURLcode    result;

    if(pFile)
    {
        CURL* pCurl = curl_easy_init();
        if(pCurl)
        {
            curl_easy_setopt(pCurl, CURLOPT_URL, url.c_str());
            curl_easy_setopt(pCurl, CURLOPT_USERPWD, "login:pass");
            curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, pFile);

            curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1l);

            curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 5*3600l);
            curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 60l);
            curl_easy_setopt(pCurl, CURLOPT_FTP_RESPONSE_TIMEOUT, 15l);
            curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_TIME, 15l);
            curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_LIMIT, 1l);

			char errorBuffer[CURL_ERROR_SIZE]={'\0'};
            curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, errorBuffer);

            struct stat fileStat;
            if ( not stat( destFilePath.c_str(), &fileStat ) )
            {
                cout << fileStat.st_size << " Bytes have been already downloaded of file: " << destFilePath << endl;
                curl_easy_setopt(pCurl, CURLOPT_RESUME_FROM, fileStat.st_size);
            }

            result = curl_easy_perform(pCurl);
            cout << "Downloading file \"" << url << "\" error code: " << (int) result << " " << curl_easy_strerror(result)
		      << ", errorBuffer: " << errorBuffer << endl;
			  
            curl_easy_cleanup(pCurl);
        }
		
		fclose(pFile);
    }
    else
    {
        cout << "Could not open file handle to target of download: " << destFilePath << endl;
        result = CURLE_FILE_COULDNT_READ_FILE;
    }

    if(result != CURLE_OK)
        return false;
    
    return true;
}

int main(int argc, char** argv)
{
	if(argc != 3)
	{
		cout << "Two parameters expected: url and destination path" << endl;
		return 2;
	}
	
	string url(argv[1]);
	string destPath(argv[2]);
		
	cout << "File " << url << " will be downloaded to " << destPath << endl;
	
	int status;
	const int RETRY_DELAY_SEC = 20;
	int tries_remaining=30;
	do
	{
		status = DownloadFile(url, destPath);
		if (status)
			break;
		else
			sleep(RETRY_DELAY_SEC);
			
		--tries_remaining;
	} while (tries_remaining > 0);

	if (!status) {
		cout << "OPERATION FAILED" << endl;
		return 1;            
	} else {
		cout << "operation successfull" << endl;
	}
	
	return 0;
}
