/*
 * Copyright (C) 2019 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 "perfstatsd"

#include <perfstatsd.h>
#include <perfstatsd_service.h>

enum MODE { DUMP_HISTORY, SET_OPTION };

android::sp<Perfstatsd> perfstatsdSp;

void *perfstatsdMain(void *) {
    LOG_TO(SYSTEM, INFO) << "main thread started";
    perfstatsdSp = new Perfstatsd();

    while (true) {
        perfstatsdSp->refresh();
        perfstatsdSp->pause();
    }
    return NULL;
}

void help(char **argv) {
    std::string usage = argv[0];
    usage = "Usage: " + usage + " [-s][-d][-o]\n" +
            "Options:\n"
            "    -s, start as service\n"
            "    -d, dump perf stats history for dumpstate_board\n"
            "    -o, set key/value option";

    fprintf(stderr, "%s\n", usage.c_str());
}

int startService(void) {
    pthread_t perfstatsdMainThread;
    errno = pthread_create(&perfstatsdMainThread, NULL, perfstatsdMain, NULL);
    if (errno != 0) {
        PLOG_TO(SYSTEM, ERROR) << "Failed to create main thread";
        return -1;
    } else {
        pthread_setname_np(perfstatsdMainThread, "perfstatsd_main");
    }

    android::ProcessState::initWithDriver("/dev/vndbinder");

    if (PerfstatsdPrivateService::start() != android::OK) {
        PLOG_TO(SYSTEM, ERROR) << "Failed to start perfstatsd service";
        return -1;
    } else
        LOG_TO(SYSTEM, INFO) << "perfstatsd_pri_service started";

    android::ProcessState::self()->startThreadPool();
    android::IPCThreadState::self()->joinThreadPool();
    pthread_join(perfstatsdMainThread, NULL);
    return 0;
}

int serviceCall(int mode, const std::string &key, const std::string &value) {
    android::ProcessState::initWithDriver("/dev/vndbinder");

    android::sp<IPerfstatsdPrivate> perfstatsdPrivateService = getPerfstatsdPrivateService();
    if (perfstatsdPrivateService == NULL) {
        PLOG_TO(SYSTEM, ERROR) << "Cannot find perfstatsd service.";
        fprintf(stdout, "Cannot find perfstatsd service.\n");
        return -1;
    }

    switch (mode) {
        case DUMP_HISTORY: {
            std::string history;
            LOG_TO(SYSTEM, INFO) << "dump perfstats history.";
            if (!perfstatsdPrivateService->dumpHistory(&history).isOk() || history.empty()) {
                PLOG_TO(SYSTEM, ERROR) << "perf stats history is not available";
                fprintf(stdout, "perf stats history is not available\n");
                return -1;
            }
            fprintf(stdout, "%s\n", history.c_str());
            break;
        }
        case SET_OPTION:
            LOG_TO(SYSTEM, INFO) << "set option: " << key << " , " << value;
            if (!perfstatsdPrivateService
                     ->setOptions(std::forward<const std::string>(key),
                                  std::forward<const std::string>(value))
                     .isOk()) {
                PLOG_TO(SYSTEM, ERROR) << "fail to set options";
                fprintf(stdout, "fail to set options\n");
                return -1;
            }
            break;
    }
    return 0;
}

int serviceCall(int mode) {
    std::string empty("");
    return serviceCall(mode, empty, empty);
}

int main(int argc, char **argv) {
    int c;
    while ((c = getopt(argc, argv, "sdo:h")) != -1) {
        switch (c) {
            case 's':
                return startService();
            case 'd':
                return serviceCall(DUMP_HISTORY);
            case 'o':
                // set options
                if (argc == 4) {
                    std::string key(argv[2]);
                    std::string value(argv[3]);
                    return serviceCall(SET_OPTION, std::move(key), std::move(value));
                }
                FALLTHROUGH_INTENDED;
            case 'h':
                // print usage
                FALLTHROUGH_INTENDED;
            default:
                help(argv);
                return 2;
        }
    }
    return 0;
}
