// Copyright 2015 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

#include "android/curl-support.h"

#include "android/openssl-support.h"
#include "android/utils/debug.h"
#include "android/utils/system.h"

#include <curl/curl.h>

#include <stdlib.h>
#include <string.h>

static int initCount = 0;
static char* cached_ca_info = NULL;

bool curl_init(const char* ca_info) {
    if (initCount == 0) {
        // first time - try to initialize the library
        const CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
        if (res != CURLE_OK) {
            dwarning("CURL: global init failed with code %d (%s)", res,
                     curl_easy_strerror(res));
            return false;
        }
        if (!android_openssl_init()) {
            return false;
        }
    }

    free(cached_ca_info);
    cached_ca_info = NULL;
    if (ca_info != NULL) {
        cached_ca_info = strdup(ca_info);
    }
    ++initCount;
    return true;
}

void curl_cleanup() {
    if (initCount == 0) {
        return;
    } else if (--initCount == 0) {
        free(cached_ca_info);
        cached_ca_info = NULL;
        // We know we're leaking memory by not calling curl_global_cleanup.
        // We can not guarantee that no threads exist when the program exits
        // (e.g. android::base::async has unknown lifetime).
        //
        // Ditto for android_openssl_finish.
    }
}

void* curl_easy_default_init(char** error) {
    // |curl_easy_init| will try to initialize libcurl globally if it isn't
    // already initialized. This behaviour is dangerous in multi-threaded
    // environment.
    if (!initCount) {
        *error = strdup("libcurl is not initialized. Bailing.");
        return NULL;
    }

    CURL* curl = curl_easy_init();
    CURLcode curlRes;

    if (!curl) {
        *error = strdup("Failed to initialize libcurl");
        return NULL;
    }

    curlRes = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
    if (curlRes != CURLE_OK) {
        asprintf(error, "Could not disable signals: %s",
                 curl_easy_strerror(curlRes));
        curl_easy_cleanup(curl);
        return NULL;
    }

    if (cached_ca_info != NULL) {
        curlRes = curl_easy_setopt(curl, CURLOPT_CAINFO, cached_ca_info);
        if (curlRes != CURLE_OK) {
            asprintf(error, "Could not set CURLOPT_CAINFO: %s",
                     curl_easy_strerror(curlRes));
            curl_easy_cleanup(curl);
            return NULL;
        }
    }
    return curl;
}

// A CurlWriteCallback that drops any downloaded data.
// Using it avoids dumping the content to stdout, the default CURL behaviour.
static size_t null_write_callback(char* ptr,
                                  size_t size,
                                  size_t nmemb,
                                  void* userdata) {
    return size * nmemb;
}

// This function can block forever. We do not set any timeout for
// curl_easy_perform. Since we disable signals, the DNS lookup timeout is ignore
// by libcurl.
// TODO: build using c-ares, and set timeout for curl_easy_perform.
static bool curl_download_internal(const char* url,
                                   const char* post_fields,
                                   CurlWriteCallback callback_func,
                                   void* callback_userdata,
                                   bool allow_404,
                                   char** error) {
    CURL* curl = curl_easy_default_init(error);
    if (!curl) {
        return false;
    }

    bool result = false;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    if (callback_func) {
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback_func);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, callback_userdata);
    } else {
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, null_write_callback);
    }

    if (post_fields) {
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_fields);
    }

    const CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        asprintf(error, "%s", curl_easy_strerror(res));
    } else {
        // toolbar returns a 404 by design.
        long http_response = 0;
        int curlRes = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_response);
        if (curlRes == CURLE_OK) {
            if (http_response == 200) {
                result = true;
            } else if (http_response == 404 && allow_404) {
                result = true;
            } else {
                asprintf(error, "%s", curl_easy_strerror(curlRes));
            }
        } else {
            asprintf(error, "Unexpected error while checking http response: %s",
                    curl_easy_strerror(curlRes));
        }
    }

    curl_easy_cleanup(curl);

    return result;
}

bool curl_download(const char* url,
                   const char* post_fields,
                   CurlWriteCallback callback_func,
                   void* callback_userdata,
                   char** error) {
    return curl_download_internal(url, post_fields, callback_func, callback_userdata, false, error);
}

extern bool curl_download_null(const char* url,
                               const char* post_fields,
                               bool allow_404,
                               char** error) {
    return curl_download_internal(url, post_fields, NULL, NULL, allow_404, error);
}
