/*
 * Copyright (C) 2016 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.
 */

#define LOG_TAG "incident"

#include "incident_sections.h"

#include <android/os/BnIncidentReportStatusListener.h>
#include <android/os/IIncidentManager.h>
#include <android/os/IncidentReportArgs.h>
#include <android/util/ProtoOutputStream.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <utils/Looper.h>

#include <cstring>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

using namespace android;
using namespace android::base;
using namespace android::binder;
using namespace android::os;
using android::util::FIELD_COUNT_SINGLE;
using android::util::FIELD_TYPE_STRING;
using android::util::ProtoOutputStream;

// ================================================================================
class StatusListener : public BnIncidentReportStatusListener {
public:
    StatusListener();
    virtual ~StatusListener();

    virtual Status onReportStarted();
    virtual Status onReportSectionStatus(int32_t section, int32_t status);
    virtual Status onReportServiceStatus(const String16& service, int32_t status);
    virtual Status onReportFinished();
    virtual Status onReportFailed();

    int getExitCodeOrElse(int defaultCode);
 private:
    int mExitCode;
};

StatusListener::StatusListener(): mExitCode(-1)
{
}

StatusListener::~StatusListener()
{
}

Status
StatusListener::onReportStarted()
{
    return Status::ok();
}

Status
StatusListener::onReportSectionStatus(int32_t section, int32_t status)
{
    fprintf(stderr, "section %d status %d\n", section, status);
    ALOGD("section %d status %d\n", section, status);
    return Status::ok();
}

Status
StatusListener::onReportServiceStatus(const String16& service, int32_t status)
{
    fprintf(stderr, "service '%s' status %d\n", String8(service).c_str(), status);
    ALOGD("service '%s' status %d\n", String8(service).c_str(), status);
    return Status::ok();
}

Status
StatusListener::onReportFinished()
{
    fprintf(stderr, "done\n");
    ALOGD("done\n");
    mExitCode = 0;
    return Status::ok();
}

Status
StatusListener::onReportFailed()
{
    fprintf(stderr, "failed\n");
    ALOGD("failed\n");
    mExitCode = 1;
    return Status::ok();
}

int
StatusListener::getExitCodeOrElse(int defaultCode) {
    return mExitCode == -1 ? defaultCode : mExitCode;
}

// ================================================================================
static void section_list(FILE* out) {
    IncidentSection sections[INCIDENT_SECTION_COUNT];
    int i = 0;
    int j = 0;
    // sort the sections based on id
    while (i < INCIDENT_SECTION_COUNT) {
        IncidentSection curr = INCIDENT_SECTIONS[i];
        for (int k = 0; k < j; k++) {
            if (curr.id > sections[k].id) {
                continue;
            }
            IncidentSection tmp = curr;
            curr = sections[k];
            sections[k] = tmp;
        }
        sections[j] = curr;
        i++;
        j++;
    }

    fprintf(out, "available sections:\n");
    for (int i = 0; i < INCIDENT_SECTION_COUNT; ++i) {
        fprintf(out, "id: %4d, name: %s\n", sections[i].id, sections[i].name);
    }
}

// ================================================================================
static IncidentSection const*
find_section(const char* name)
{
    ssize_t low = 0;
    ssize_t high = INCIDENT_SECTION_COUNT - 1;

    while (low <= high) {
        ssize_t mid = (low + high) / 2;
        IncidentSection const* section = INCIDENT_SECTIONS + mid;

        int cmp = strcmp(section->name, name);
        if (cmp < 0) {
            low = mid + 1;
        } else if (cmp > 0) {
            high = mid - 1;
        } else {
            return section;
        }
    }
    return NULL;
}

// ================================================================================
static int
get_privacy_policy(const char* arg)
{
    if (strcmp(arg, "L") == 0
        || strcmp(arg, "LOCAL") == 0) {
      return PRIVACY_POLICY_LOCAL;
    }
    if (strcmp(arg, "E") == 0
        || strcmp(arg, "EXPLICIT") == 0) {
      return PRIVACY_POLICY_EXPLICIT;
    }
    if (strcmp(arg, "A") == 0
        || strcmp(arg, "AUTO") == 0
        || strcmp(arg, "AUTOMATIC") == 0) {
      return PRIVACY_POLICY_AUTOMATIC;
    }
    return -1; // return the default value
}

// ================================================================================
static bool
parse_receiver_arg(const string& arg, string* pkg, string* cls)
{
    if (arg.length() == 0) {
        return true;
    }
    size_t slash = arg.find('/');
    if (slash == string::npos) {
        return false;
    }
    if (slash == 0 || slash == arg.length() - 1) {
        return false;
    }
    if (arg.find('/', slash+1) != string::npos) {
        return false;
    }
    pkg->assign(arg, 0, slash);
    cls->assign(arg, slash+1);
    if ((*cls)[0] == '.') {
        *cls = (*pkg) + (*cls);
    }
    return true;
}

// ================================================================================
static int
stream_output(const int read_fd, const int write_fd) {
    while (true) {
        int amt = splice(read_fd, NULL, write_fd, NULL, 4096, 0);
        if (amt < 0) {
            return errno;
        } else if (amt == 0) {
            return 0;
        }
    }
}

// ================================================================================
static void
usage(FILE* out)
{
    fprintf(out, "usage: incident OPTIONS [SECTION...]\n");
    fprintf(out, "\n");
    fprintf(out, "Takes an incident report.\n");
    fprintf(out, "\n");
    fprintf(out, "OPTIONS\n");
    fprintf(out, "  -l           list available sections\n");
    fprintf(out, "  -p           privacy spec, LOCAL, EXPLICIT or AUTOMATIC. Default AUTOMATIC.\n");
    fprintf(out, "  -r REASON    human readable description of why the report is taken.\n");
    fprintf(out, "  -z           gzip the incident report, i.e. pipe the output through gzip.\n");
    fprintf(out, "\n");
    fprintf(out, "and one of these destinations:\n");
    fprintf(out, "  -b           (default) print the report to stdout (in proto format)\n");
    fprintf(out, "  -d           send the report into dropbox\n");
    fprintf(out, "  -u           print a full report to stdout for dumpstate to zip as a bug\n");
    fprintf(out, "               report. SECTION is ignored. Should only be called by dumpstate.\n");
    fprintf(out, "  -s PKG/CLS   send broadcast to the broadcast receiver.\n");
    fprintf(out, "\n");
    fprintf(out, "  SECTION     the field numbers of the incident report fields to include\n");
    fprintf(out, "\n");
}

int
main(int argc, char** argv)
{
    Status status;
    IncidentReportArgs args;
    enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST, DEST_DUMPSTATE } destination = DEST_UNSET;
    int privacyPolicy = PRIVACY_POLICY_AUTOMATIC;
    string reason;
    string receiverArg;

    // Parse the args
    int opt;
    while ((opt = getopt(argc, argv, "bhdlp:r:s:uz")) != -1) {
        switch (opt) {
            case 'h':
                usage(stdout);
                return 0;
            case 'l':
                section_list(stdout);
                return 0;
            case 'b':
                if (!(destination == DEST_UNSET || destination == DEST_STDOUT)) {
                    usage(stderr);
                    return 1;
                }
                destination = DEST_STDOUT;
                break;
            case 'd':
                if (!(destination == DEST_UNSET || destination == DEST_DROPBOX)) {
                    usage(stderr);
                    return 1;
                }
                destination = DEST_DROPBOX;
                break;
            case 'u':
                if (!(destination == DEST_UNSET || destination == DEST_DUMPSTATE)) {
                    usage(stderr);
                    return 1;
                }
                destination = DEST_DUMPSTATE;
                break;
            case 'p':
                privacyPolicy = get_privacy_policy(optarg);
                break;
            case 'r':
                if (reason.size() > 0) {
                    usage(stderr);
                    return 1;
                }
                reason = optarg;
                break;
            case 's':
                if (destination != DEST_UNSET) {
                    usage(stderr);
                    return 1;
                }
                destination = DEST_BROADCAST;
                receiverArg = optarg;
                break;
            case 'z':
                args.setGzip(true);
                break;
            default:
                usage(stderr);
                return 1;
        }
    }
    if (destination == DEST_UNSET) {
        destination = DEST_STDOUT;
    }

    string pkg;
    string cls;
    if (parse_receiver_arg(receiverArg, &pkg, &cls)) {
        args.setReceiverPkg(pkg);
        args.setReceiverCls(cls);
    } else {
        fprintf(stderr, "badly formatted -s package/class option: %s\n\n", receiverArg.c_str());
        usage(stderr);
        return 1;
    }

    if (optind == argc) {
        args.setAll(true);
    } else {
        for (int i=optind; i<argc; i++) {
            const char* arg = argv[i];
            char* end;
            if (arg[0] != '\0') {
                int section = strtol(arg, &end, 0);
                if (*end == '\0') {
                    args.addSection(section);
                } else {
                    IncidentSection const* ic = find_section(arg);
                    if (ic == NULL) {
                        ALOGD("Invalid section: %s\n", arg);
                        fprintf(stderr, "Invalid section: %s\n", arg);
                        return 1;
                    }
                    args.addSection(ic->id);
                }
            }
        }
    }
    args.setPrivacyPolicy(privacyPolicy);

    if (reason.size() > 0) {
        ProtoOutputStream proto;
        proto.write(/* reason field id */ 2 | FIELD_TYPE_STRING | FIELD_COUNT_SINGLE, reason);
        vector<uint8_t> header;
        proto.serializeToVector(&header);
        args.addHeader(header);
    }

    // Start the thread pool.
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
    ps->giveThreadPoolName();

    // Look up the service
    sp<IIncidentManager> service = interface_cast<IIncidentManager>(
            defaultServiceManager()->getService(android::String16("incident")));
    if (service == NULL) {
        fprintf(stderr, "Couldn't look up the incident service\n");
        return 1;
    }

    // Construct the stream
    int fds[2];
    pipe(fds);

    unique_fd readEnd(fds[0]);
    unique_fd writeEnd(fds[1]);

    if (destination == DEST_STDOUT) {
        // Call into the service
        sp<StatusListener> listener(new StatusListener());
        status = service->reportIncidentToStream(args, listener, std::move(writeEnd));

        if (!status.isOk()) {
            fprintf(stderr, "reportIncident returned \"%s\"\n", status.toString8().c_str());
            return 1;
        }

        // Wait for the result and print out the data they send.
        //IPCThreadState::self()->joinThreadPool();
        return listener->getExitCodeOrElse(stream_output(fds[0], STDOUT_FILENO));
    } else if (destination == DEST_DUMPSTATE) {
        // Call into the service
        sp<StatusListener> listener(new StatusListener());
        status = service->reportIncidentToDumpstate(std::move(writeEnd), listener);
        if (!status.isOk()) {
            fprintf(stderr, "reportIncident returned \"%s\"\n", status.toString8().c_str());
            return 1;
        }
        return listener->getExitCodeOrElse(stream_output(fds[0], STDOUT_FILENO));
    } else {
        status = service->reportIncident(args);
        if (!status.isOk()) {
            fprintf(stderr, "reportIncident returned \"%s\"\n", status.toString8().c_str());
            return 1;
        } else {
            return 0;
        }
    }

}
