// 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/CrashService_linux.h"

#include "android/base/files/PathUtils.h"
#include "android/base/system/System.h"

#include "android/crashreport/CrashService.h"

#include "android/crashreport/CrashSystem.h"
#include "android/utils/debug.h"
#include "android/utils/path.h"

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <memory>

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

#define HWINFO_CMD "lshw"

namespace android {

using ::android::base::PathUtils;
using ::android::base::System;

namespace crashreport {

HostCrashService::~HostCrashService() {
    stopCrashServer();
}

void HostCrashService::OnClientDumpRequest(
        void* context,
        const ::google_breakpad::ClientInfo* client_info,
        const ::std::string* file_path) {
    if (static_cast<CrashService::DumpRequestContext*>(context)
                ->file_path.empty()) {
        D("Client Requesting dump %s\n", file_path->c_str());
        static_cast<CrashService::DumpRequestContext*>(context)->file_path =
                *file_path;
    }
}

void HostCrashService::OnClientExit(
        void* context,
        const ::google_breakpad::ClientInfo* client_info) {
    D("Client exiting\n");
    CrashService::ServerState* serverstate =
            static_cast<CrashService::ServerState*>(context);
    if (serverstate->connected > 0) {
        serverstate->connected -= 1;
    }
    if (serverstate->connected == 0) {
        serverstate->waiting = false;
    }
}

bool HostCrashService::startCrashServer(const std::string& pipe) {
    const int listen_fd = std::stoi(pipe);
    if (mCrashServer) {
        return false;
    }

    initCrashServer();

    mCrashServer.reset(new ::google_breakpad::CrashGenerationServer(
            listen_fd, OnClientDumpRequest, &mDumpRequestContext, OnClientExit,
            &mServerState, true, &CrashSystem::get()->getCrashDirectory()));

    return mCrashServer->Start();
}

bool HostCrashService::stopCrashServer() {
    if (mCrashServer) {
        mCrashServer.reset();
        return true;
    } else {
        return false;
    }
}

bool HostCrashService::isClientAlive() {
    if (!mClientPID) {
        return 0;
    }
    // waitpid for child clients
    waitpid(mClientPID, nullptr, WNOHANG);
    // kill with 0 signal will return non 0 if process does not exist
    if (kill(mClientPID, 0) != 0) {
        return false;
    } else {
        return true;
    }
}

bool HostCrashService::getHWInfo() {
    std::string data_directory = getDataDirectory();
    if (data_directory.empty()) {
        E("Unable to get data directory for crash report attachments");
        return false;
    }
    std::string file_path = PathUtils::join(data_directory, kHwInfoName);

    std::string syscmd(HWINFO_CMD);
    syscmd += " > ";
    syscmd += file_path;
    fprintf(stderr, "Running '%s' to get hardware info", syscmd.c_str());
    int status = system(syscmd.c_str());

    if (status != 0) {
        E("Unable to get hardware info for crash report");
        return false;
    }
    return true;
}

bool HostCrashService::getMemInfo() {
    // /proc/meminfo contains all the details we need so just upload that
    std::string file_path = PathUtils::join(getDataDirectory(), kMemInfoName);
    return path_copy_file(file_path.c_str(), "/proc/meminfo") == 0;
}

}  // namespace crashreport
}  // namespace android
