// 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.

#include "android/crashreport/CrashReporter.h"

#include "android/base/memory/LazyInstance.h"
#include "android/base/system/System.h"
#include "android/base/system/Win32UnicodeString.h"
#include "android/utils/debug.h"
#include "client/windows/handler/exception_handler.h"

#include <psapi.h>

#include <memory>

#include <inttypes.h>
#include <stdint.h>

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

namespace android {
namespace crashreport {

namespace {

class HostCrashReporter : public CrashReporter {
public:
    HostCrashReporter() : CrashReporter(), mHandler() {}

    virtual ~HostCrashReporter() {}

    bool attachCrashHandler(const CrashSystem::CrashPipe& crashpipe) override {
        if (mHandler) {
            return false;
        }

        ::android::base::Win32UnicodeString dumpDir(getDumpDir().c_str(),
                                                    getDumpDir().length());
        std::wstring dumpDir_wstr(dumpDir.c_str());

        ::android::base::Win32UnicodeString crashPipe(crashpipe.mClient.c_str(),
                                                    crashpipe.mClient.length());

        // google_breakpad::ExceptionHandler makes a local copy of dumpDir arg.
        // crashPipe arg is copied locally during ExceptionHandler's construction
        // of CrashGenerationClient.
        mHandler.reset(new google_breakpad::ExceptionHandler(
                dumpDir_wstr, &HostCrashReporter::exceptionFilterCallback,
                nullptr, nullptr,
                google_breakpad::ExceptionHandler::HANDLER_ALL, MiniDumpNormal,
                crashPipe.c_str(), nullptr));
        return mHandler != nullptr;
    }

    bool waitServicePipeReady(const std::string& pipename,
                              int timeout_ms) override {
        static_assert(kWaitIntervalMS > 0, "kWaitIntervalMS must be greater than 0");
        ::android::base::Win32UnicodeString pipename_unicode(pipename.c_str(),
                                                             pipename.length());
        for (; timeout_ms > 0; timeout_ms -= kWaitIntervalMS) {
            if (WaitNamedPipeW(pipename_unicode.c_str(), timeout_ms) != 0) {
                return true;
            }

            if (GetLastError() == ERROR_SEM_TIMEOUT) {
                // Pipe exists but timed out waiting to become ready
                return false;
            } else {
                // Pipe does not exist yet, sleep and try again
                ::android::base::System::get()->sleepMs(kWaitIntervalMS);
            }

        }
        return false;
    }

    void setupChildCrashProcess(int pid) override {}

    void writeDump() override { mHandler->WriteMinidump(); }

private:
    static bool exceptionFilterCallback(
        void*,
        EXCEPTION_POINTERS*,
        MDRawAssertionInfo*);

    bool onCrashPlatformSpecific() override;

    std::unique_ptr<google_breakpad::ExceptionHandler> mHandler;
};

::android::base::LazyInstance<HostCrashReporter> sCrashReporter =
        LAZY_INSTANCE_INIT;

bool HostCrashReporter::exceptionFilterCallback(
    void*,
    EXCEPTION_POINTERS*,
    MDRawAssertionInfo*) {
    return CrashReporter::get()->onCrash();
}

static void attachMemoryInfo()
{
    PROCESS_MEMORY_COUNTERS_EX memCounters = {sizeof(memCounters)};
    if (::GetProcessMemoryInfo(::GetCurrentProcess(),
                reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&memCounters),
                sizeof(memCounters))) {
        char buf[1024] = {};
        snprintf(buf, sizeof(buf) - 1,
            "PageFaultCount: %" PRIu64 "\n"
            "PeakWorkingSetSize: %" PRIu64 " kB\n"
            "WorkingSetSize: %" PRIu64 " kB\n"
            "QuotaPeakPagedPoolUsage: %" PRIu64 " kB\n"
            "QuotaPagedPoolUsage: %" PRIu64 " kB\n"
            "QuotaPeakNonPagedPoolUsage: %" PRIu64 " kB\n"
            "QuotaNonPagedPoolUsage: %" PRIu64 " kB\n"
            "PagefileUsage (commit): %" PRIu64 " kB\n"
            "PeakPagefileUsage: %" PRIu64 " kB\n",
            uint64_t(memCounters.PageFaultCount),
            uint64_t(memCounters.PeakWorkingSetSize / 1024),
            uint64_t(memCounters.WorkingSetSize / 1024),
            uint64_t(memCounters.QuotaPeakPagedPoolUsage / 1024),
            uint64_t(memCounters.QuotaPagedPoolUsage / 1024),
            uint64_t(memCounters.QuotaPeakNonPagedPoolUsage / 1024),
            uint64_t(memCounters.QuotaNonPagedPoolUsage / 1024),
            uint64_t((memCounters.PagefileUsage
                ? memCounters.PagefileUsage
                : memCounters.PrivateUsage) / 1024),
            uint64_t(memCounters.PeakPagefileUsage / 1024));

        CrashReporter::get()->attachData(
                    CrashReporter::kProcessMemoryInfoFileName, buf);
    }
}

bool HostCrashReporter::onCrashPlatformSpecific() {
    // collect the memory usage at the time of the crash
    attachMemoryInfo();
    return true;
}

}  // namespace anonymous

CrashReporter* CrashReporter::get() {
    return sCrashReporter.ptr();
}

}  // namespace crashreport
}  // namespace android
