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

#include "Log.h"

#include "StatsService.h"
#include "logd/LogReader.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 <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

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

// ================================================================================
/**
 * 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);

    // Tell StatsService that we're ready to go.
    data->service->Startup();

    // 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.
    log_reader_thread_data* data = new 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));
    if (err != NO_ERROR) {
        pthread_attr_destroy(&attr);
        return err;
    }
    pthread_attr_destroy(&attr);

    return NO_ERROR;
}

// ================================================================================
int main(int /*argc*/, char** /*argv*/) {
    status_t err;

    // Set up the looper
    sp<Looper> looper(Looper::prepare(0 /* opts */));

    // Set up the binder
    sp<ProcessState> ps(ProcessState::self());
    ps->setThreadPoolMaxThreadCount(1);  // everything is oneway, let it queue and save ram
    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;
    }

    // TODO: This line is temporary, since statsd doesn't start up automatically (and therefore
    // the call in StatsService::SystemRunning() won't ever be called right now).
    // TODO: Are you sure? Don't we need to reconnect to the system process if we get restarted?
    //  --joeo
    service->sayHiToStatsCompanion();

    // Start the log reader thread
    err = start_log_reader_thread(service);
    if (err != NO_ERROR) {
        return 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;
}
