/*
 * Copyright (C) 2017 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 DEBUG false  // STOPSHIP if true
#include "Log.h"

#include "StatsService.h"
#include "logd/LogReader.h"
#include "socket/StatsSocketListener.h"

#include <binder/IInterface.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
#include <binder/Status.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>

#include <memory>

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

using namespace android;
using namespace android::os::statsd;

const bool kUseLogd = false;
const bool kUseStatsdSocket = true;

/**
 * Thread function data.
 */
struct log_reader_thread_data {
    sp<StatsService> service;
};

/**
 * Thread func for where the log reader runs.
 */
static void* log_reader_thread_func(void* cookie) {
    log_reader_thread_data* data = static_cast<log_reader_thread_data*>(cookie);
    sp<LogReader> reader = new LogReader(data->service);

    // Run the read loop. Never returns.
    reader->Run();

    ALOGW("statsd LogReader.Run() is not supposed to return.");

    delete data;
    return NULL;
}

/**
 * Creates and starts the thread to own the LogReader.
 */
static status_t start_log_reader_thread(const sp<StatsService>& service) {
    status_t err;
    pthread_attr_t attr;
    pthread_t thread;

    // Thread data.
    std::unique_ptr<log_reader_thread_data> data = std::make_unique<log_reader_thread_data>();
    data->service = service;

    // Create the thread
    err = pthread_attr_init(&attr);
    if (err != NO_ERROR) {
        return err;
    }
    // TODO: Do we need to tweak thread priority?
    err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (err != NO_ERROR) {
        pthread_attr_destroy(&attr);
        return err;
    }
    err = pthread_create(&thread, &attr, log_reader_thread_func,
                         static_cast<void*>(data.get()));
    if (err != NO_ERROR) {
        pthread_attr_destroy(&attr);
        return err;
    }
    // Release here rather than in pthread_create, since an error creating the
    // thread leaves `data` ownerless.
    data.release();
    pthread_attr_destroy(&attr);

    return NO_ERROR;
}

int main(int /*argc*/, char** /*argv*/) {
    // Set up the looper
    sp<Looper> looper(Looper::prepare(0 /* opts */));

    // Set up the binder
    sp<ProcessState> ps(ProcessState::self());
    ps->setThreadPoolMaxThreadCount(9);
    ps->startThreadPool();
    ps->giveThreadPoolName();
    IPCThreadState::self()->disableBackgroundScheduling(true);

    // Create the service
    sp<StatsService> service = new StatsService(looper);
    if (defaultServiceManager()->addService(String16("stats"), service) != 0) {
        ALOGE("Failed to add service");
        return -1;
    }
    service->sayHiToStatsCompanion();

    service->Startup();

    sp<StatsSocketListener> socketListener = new StatsSocketListener(service);

    if (kUseLogd) {
        ALOGI("using logd");
        // Start the log reader thread
        status_t err = start_log_reader_thread(service);
        if (err != NO_ERROR) {
            return 1;
        }
    }

    if (kUseStatsdSocket) {
        ALOGI("using statsd socket");
        // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
        if (socketListener->startListener(600)) {
            exit(1);
        }
    }

    // Loop forever -- the reports run on this thread in a handler, and the
    // binder calls remain responsive in their pool of one thread.
    while (true) {
        looper->pollAll(-1 /* timeoutMillis */);
    }
    ALOGW("statsd escaped from its loop.");

    return 1;
}
