// Copyright 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifdef _WIN32
// To avoid a compiler warning that asks to include this before <windows.h>
// which is included by <curl/curl.h>. This must appear before other includes.
#include <winsock2.h>
#endif

#include "android/crashreport/CrashService.h"

#include "android/crashreport/CrashReporter.h"

#ifdef _WIN32
#include "android/crashreport/CrashService_windows.h"
#elif defined(__APPLE__)
#include "android/crashreport/CrashService_darwin.h"
#elif defined(__linux__)
#include "android/crashreport/CrashService_linux.h"
#else
#error "Unsupported platform"
#endif

#include "android/base/files/PathUtils.h"
#include "android/base/StringFormat.h"
#include "android/base/system/System.h"
#include "android/crashreport/CrashSystem.h"
#include "android/curl-support.h"
#include "android/utils/debug.h"
#include "google_breakpad/processor/fast_source_line_resolver.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/code_module.h"
#include "google_breakpad/processor/code_modules.h"
#include "google_breakpad/processor/minidump.h"
#include "google_breakpad/processor/minidump_processor.h"
#include "google_breakpad/processor/stack_frame_cpu.h"
#include "processor/stackwalk_common.h"
#include "processor/pathname_stripper.h"

#include <curl/curl.h>

#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#define E(...) derror(__VA_ARGS__)
#define W(...) dwarning(__VA_ARGS__)
#define D(...) VERBOSE_PRINT(init, __VA_ARGS__)
#define I(...) printf(__VA_ARGS__)

#define WAIT_INTERVAL_MS 100

using android::base::PathUtils;
using android::base::StringFormat;
using android::base::StringView;
using android::base::System;

extern "C" const unsigned char* android_emulator_icon_find(const char* name,
                                                           size_t* psize);

const char kNameKey[] = "prod";
const char kVersionKey[] = "ver";
const char kName[] = "AndroidEmulator";
const char kCommentsKey[] = "comments";

// Callback to get the response data from server.
static size_t WriteCallback(void* ptr, size_t size, size_t nmemb, void* userp) {
    if (!userp)
        return 0;

    auto& response = *static_cast<std::string*>(userp);
    size_t real_size = size * nmemb;
    response.append(static_cast<char*>(ptr), real_size);
    return real_size;
}

namespace android {
namespace crashreport {

const char* const CrashService::kHwInfoName = "hw_info.txt";
const char* const CrashService::kMemInfoName = "mem_info.txt";

CrashService::CrashService(const std::string& version,
                           const std::string& build,
                           const char* dataDir)
    : mDumpRequestContext(),
      mServerState(),
      mDataDirectory(dataDir ? dataDir : ""),
      mVersion(version),
      mBuild(build),
      mVersionId(),
      mDumpFile(),
      mReportId(),
      mComments(),
      mDidCrashOnExit(false) {
    mVersionId = version;
    mVersionId += "-";
    mVersionId += build;
};

CrashService::~CrashService() {
    if (validDumpFile()) {
        remove(mDumpFile.c_str());
    }
    if (!mDataDirectory.empty()) {
        const auto files = System::get()->scanDirEntries(mDataDirectory, true);
        for (const std::string& file : files) {
            remove(file.c_str());
        }
        if (remove(mDataDirectory.c_str()) < 0) {
            // on Windows waiting a bit usually helps
            System::get()->sleepMs(1);
            remove(mDataDirectory.c_str());
        }
    }
}

void CrashService::setDumpFile(const std::string& dumpfile) {
    mDumpFile = dumpfile;
}

std::string CrashService::getDumpFile() const {
    return mDumpFile;
}

bool CrashService::validDumpFile() const {
    return ::android::crashreport::CrashSystem::get()->isDump(mDumpFile);
}

std::string CrashService::getReport() {
    // Capture printf's from PrintProcessState to file
    std::string reportFile(mDumpFile);
    reportFile += "report";

    FILE* fp = fopen(reportFile.c_str(), "w+");
    if (!fp) {
        std::string errmsg;
        errmsg += "Error, Couldn't open " + reportFile +
                  "for writing crash report.";
        errmsg += "\n";
        return errmsg;
    }
    google_breakpad::SetPrintStream(fp);
    google_breakpad::PrintProcessState(mProcessState, true, &mLineResolver);

    fprintf(fp, "thread requested=%d\n", mProcessState.requesting_thread());
    fclose(fp);

    std::string report(readFile(reportFile));
    remove(reportFile.c_str());

    return report;
}

std::string CrashService::getReportId() const {
    return mReportId;
}

const std::string& CrashService::getDumpMessage() const {
    return mDumpMessage;
}

const std::string& CrashService::getCrashOnExitMessage() const {
    return mCrashOnExitMessage;
}

bool CrashService::didCrashOnExit() const {
    return mDidCrashOnExit;
}

void CrashService::addReportValue(const std::string& key,
                                  const std::string& value) {
    mReportValues[key] = value;
}

void CrashService::addReportFile(const std::string& key,
                                 const std::string& path) {
    mReportFiles[key] = path;
}

void CrashService::addUserComments(const std::string& comments) {
    addReportValue(kCommentsKey, comments);
}

bool CrashService::uploadCrash() {
    curl_init(::android::crashreport::CrashSystem::get()
                      ->getCaBundlePath().c_str());
    char* error = nullptr;
    CURL* const curl = curl_easy_default_init(&error);
    if (!curl) {
        E("Curl instantiation failed: %s\n", error);
        ::free(error);
        return false;
    }

    curl_easy_setopt(curl, CURLOPT_URL,
                     CrashSystem::get()->getCrashURL().c_str());

    curl_httppost* formpost = nullptr;
    curl_httppost* lastptr = nullptr;

    addReportValue(kNameKey, kName);
    addReportValue(kVersionKey, mVersionId);
    addReportFile("upload_file_minidump", mDumpFile);

    for (auto const& x : mReportValues) {
        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, x.first.c_str(),
                     CURLFORM_COPYCONTENTS, x.second.c_str(), CURLFORM_END);
    }

    for (auto const& x : mReportFiles) {
        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, x.first.c_str(),
                     CURLFORM_FILE, x.second.c_str(), CURLFORM_END);
    }

    curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
    curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);

    // The 4th pointer to be passed to the WRITEFUNCTION above
    std::string http_response_data;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA,
                     static_cast<void*>(&http_response_data));

    bool success = true;
    CURLcode curlRes = curl_easy_perform(curl);

    if (curlRes != CURLE_OK) {
        success = false;
        E("curl_easy_perform() failed with code %d (%s)", curlRes,
          curl_easy_strerror(curlRes));
    } else {
        long http_response = 0;
        curlRes =
                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_response);
        if (curlRes == CURLE_OK) {
            if (http_response != 200) {
                E("Got HTTP response code %ld", http_response);
                success = false;
            }
        } else if (curlRes == CURLE_UNKNOWN_OPTION) {
            E("Can not get a valid response code: not supported");
            success = false;
        } else {
            E("Unexpected error while checking http response: %s",
              curl_easy_strerror(curlRes));
            success = false;
        }

        if (success) {
            I("Crash Report ID: %s\n", http_response_data.c_str());
            mReportId = http_response_data;
        }
    }

    curl_formfree(formpost);
    curl_easy_cleanup(curl);
    return success;
}

UserSuggestions CrashService::getSuggestions() {
    return UserSuggestions(&mProcessState);
}

bool CrashService::processCrash() {
    mMinidump.reset(new google_breakpad::Minidump(mDumpFile));
    google_breakpad::MinidumpProcessor minidump_processor(nullptr,
                                                          &mLineResolver);

    // Process the minidump.
    if (!mMinidump->Read()) {
        E("Minidump %s could not be read", mMinidump->path().c_str());
        return false;
    }
    if (minidump_processor.Process(mMinidump.get(), &mProcessState) !=
        google_breakpad::PROCESS_OK) {
        E("MinidumpProcessor::Process failed");
        return false;
    }
    return true;
}

bool CrashService::collectSysInfo() {
    // As long as one of these succeed we consider it a success, it's better to
    // upload a partial report if we have something.
    bool success = getHWInfo();
    success |= getMemInfo();

    // Now that we have all the system information as well as any data the
    // emulator placed in the data directory we can collect the files and add
    // them to the list of files in the report.
    collectDataFiles();

    return success;
}

std::unique_ptr<CrashService> CrashService::makeCrashService(
        const std::string& version,
        const std::string& build,
        const char* dataDir) {
    return std::unique_ptr<CrashService>(
            new HostCrashService(version, build, dataDir));
}

std::string CrashService::readFile(StringView path) {
    std::ifstream is(path.c_str());

    if (!is) {
        std::string errmsg;
        errmsg = std::string("Error, Can't open file ") + path.c_str() +
                 " for reading. Errno=" + std::to_string(errno) + "\n";
        return errmsg;
    }

    std::ostringstream ss;
    ss << is.rdbuf();
    return ss.str();
}

std::string CrashService::getSysInfo() {
    const auto files = System::get()->scanDirEntries(mDataDirectory, true);
    std::string info;
    for (const std::string& file : files) {
        // By convention we only show files that end with .txt, other files
        // may have binary content that will not display in a readable way.
        if (strcasecmp(PathUtils::extension(file).c_str(), ".txt") == 0) {
            // Prepend each piece with the name of the file as a separator
            std::string basename;
            if (PathUtils::split(file, nullptr, &basename)) {
                info += "---- ";
                info += basename.c_str();
                info += " ----\n";
            }
            info += readFile(file);
            info += "\n";
        }
    }
    return info;
}

void CrashService::initCrashServer() {
    mServerState.waiting = true;
    mServerState.connected = 0;
}

const std::string& CrashService::getDataDirectory() const {
    return mDataDirectory;
}

int64_t CrashService::waitForDumpFile(int clientpid, int timeout) {
    int64_t waitduration_ms = 0;
    if (!setClient(clientpid)) {
        return -1;
    }
    while (true) {
        if (!isClientAlive()) {
            if ((!mServerState.waiting) && (mServerState.connected == 0)) {
                break;
            } else {
                E("CrashService client died unexpectedly\n");
                return -1;
            }
        }
        if (timeout >= 0 && waitduration_ms >= timeout) {
            return -1;
        }
        System::get()->sleepMs(WAIT_INTERVAL_MS);
        waitduration_ms += WAIT_INTERVAL_MS;
    }
    if (!mDumpRequestContext.file_path.empty()) {
        mDumpFile = mDumpRequestContext.file_path;
    }
    return waitduration_ms;
}

bool CrashService::setClient(int clientpid) {
    // return false for invalid pid
    if (clientpid <= 0) {
        return false;
    }
    mClientPID = clientpid;
    return true;
}

void CrashService::collectProcessList()
{
    if (mDataDirectory.empty()) {
        return;
    }

    const auto command = StringFormat(
                             "ps aux >%s/%s",
                             mDataDirectory,
                             CrashReporter::kProcessListFileName);
    system(command.c_str());
}

void CrashService::retrieveDumpMessage() {
    std::string path = PathUtils::join(mDataDirectory,
                                       CrashReporter::kDumpMessageFileName);
    if (System::get()->pathIsFile(path)) {
        // remember the dump message to show it instead of the default one
        mDumpMessage = readFile(path);
    }
}

void CrashService::collectDataFiles() {
    if (mDataDirectory.empty()) {
        return;
    }

    const auto files = System::get()->scanDirEntries(mDataDirectory);
    for (const std::string& name : files) {
        const auto fullName = PathUtils::join(mDataDirectory, name);
        addReportFile(name.c_str(), fullName.c_str());
        if (name == CrashReporter::kDumpMessageFileName) {
            // remember the dump message to show it instead of the default one
            mDumpMessage = readFile(fullName);
        } else if (name == CrashReporter::kCrashOnExitFileName) {
            // remember the dump message to show it instead of the default one
            mCrashOnExitMessage = readFile(fullName);
            mDidCrashOnExit = true;
        }
    }
}

// This is a list of all substrings that definitely belong to some graphics
// drivers.
// NB: all names have to be lower-case - we transform the string from the stack
// trace to lowe case before doing the comparisons

static const char* const gfx_drivers_lcase[] = {
    // NVIDIA
    "nvcpl", // Control Panel
    "nvshell", // Desktop Explorer
    "nvinit", // initializer
    "nv4_disp", // Windows 2000 (!) display driver
    "nvcod", // CoInstaller
    "nvcuda", // Cuda
    "nvopencl", // OpenCL
    "nvcuvid", // Video decode
    "nvogl", // OpenGL (modern)
    "ig4icd", // OpenGL (icd?)
    "geforcegldriver", // OpenGL (old)
    "nvd3d", // Direct3D
    "nvwgf2", // D3D10
    "nvdx", // D3D shim drivers
    "nvml", // management library
    "nvfbc", // front buffer capture library
    "nvapi", // NVAPI Library
    "libnvidia", // NVIDIA Linux

    // ATI
    "atioglxx", // OpenGL
    "atig6txx", // OpenGL
    "r600", // Radeon r600 series
    "aticfx", // DX11
    "atiumd", // D3D
    "atidxx", // "TMM Com Clone Control Module" (???)
    "atimpenc", // video encoder
    "atigl", // another ATI OpenGL driver

    // Intel
    "i915", // Intel i915 gpu
    "igd", // 'igd' series of Intel GPU's
    "igl", // ?
    "igfx", // ?
    "ig75icd", // Intel icd
    "intelocl", // Intel OpenCL

    // Others
    "libgl.", // Low-level Linux OpenGL
    "opengl32.dll", // Low-level Windows OpenGL
};

static bool containsGfxPattern(const std::string& str) {
    for (const char* pattern : gfx_drivers_lcase) {
        if (str.find(pattern) != std::string::npos) {
            return true;
        }
    }

    return false;
}

UserSuggestions::UserSuggestions(google_breakpad::ProcessState* process_state) {
    suggestions.clear();

    // Go through all frames of the stack of
    // the thread requesting dump.

    int crashed_thread_id = process_state->requesting_thread();
    google_breakpad::CallStack* crashed_stack =
            process_state->threads()->at(crashed_thread_id);
    if (!crashed_stack) {
        return;
    }

    const int frame_count = crashed_stack->frames()->size();
    for (int frame_index = 0; frame_index < frame_count; ++frame_index) {
        google_breakpad::StackFrame* const frame =
                crashed_stack->frames()->at(frame_index);
        if (!frame) {
            continue;
        }
        const auto& module = frame->module;

        if (module) {
            std::string file = google_breakpad::PathnameStripper::File(
                    module->code_file());
            std::transform(file.begin(), file.end(), file.begin(), ::tolower);

            // Should the user update their graphics drivers?
            if (containsGfxPattern(file)) {
                suggestions.insert(Suggestion::UpdateGfxDrivers);
                break;
            }
        }
    }
}

}  // namespace crashreport
}  // namespace android
