/*
 * 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 "storaged"

#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include <android-base/logging.h>
#include <batteryservice/BatteryServiceConstants.h>
#include <batteryservice/IBatteryPropertiesRegistrar.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <log/log.h>

#include <storaged.h>
#include <storaged_utils.h>

/* disk_stats_publisher */
void disk_stats_publisher::publish(void) {
    // Logging
    struct disk_perf perf = get_disk_perf(&mAccumulate);
    log_debug_disk_perf(&perf, "regular");
    log_event_disk_stats(&mAccumulate, "regular");
    // Reset global structures
    memset(&mAccumulate, 0, sizeof(struct disk_stats));
}

void disk_stats_publisher::update(void) {
    struct disk_stats curr;
    if (parse_disk_stats(DISK_STATS_PATH, &curr)) {
        struct disk_stats inc = get_inc_disk_stats(&mPrevious, &curr);
        add_disk_stats(&inc, &mAccumulate);
#ifdef DEBUG
//            log_kernel_disk_stats(&mPrevious, "prev stats");
//            log_kernel_disk_stats(&curr, "curr stats");
//            log_kernel_disk_stats(&inc, "inc stats");
//            log_kernel_disk_stats(&mAccumulate, "accumulated stats");
#endif
        mPrevious = curr;
    }
}

/* disk_stats_monitor */
void disk_stats_monitor::update_mean() {
    CHECK(mValid);
    mMean.read_perf = (uint32_t)mStats.read_perf.get_mean();
    mMean.read_ios = (uint32_t)mStats.read_ios.get_mean();
    mMean.write_perf = (uint32_t)mStats.write_perf.get_mean();
    mMean.write_ios = (uint32_t)mStats.write_ios.get_mean();
    mMean.queue = (uint32_t)mStats.queue.get_mean();
}

void disk_stats_monitor::update_std() {
    CHECK(mValid);
    mStd.read_perf = (uint32_t)mStats.read_perf.get_std();
    mStd.read_ios = (uint32_t)mStats.read_ios.get_std();
    mStd.write_perf = (uint32_t)mStats.write_perf.get_std();
    mStd.write_ios = (uint32_t)mStats.write_ios.get_std();
    mStd.queue = (uint32_t)mStats.queue.get_std();
}

void disk_stats_monitor::add(struct disk_perf* perf) {
    mStats.read_perf.add(perf->read_perf);
    mStats.read_ios.add(perf->read_ios);
    mStats.write_perf.add(perf->write_perf);
    mStats.write_ios.add(perf->write_ios);
    mStats.queue.add(perf->queue);
}

void disk_stats_monitor::evict(struct disk_perf* perf) {
    mStats.read_perf.evict(perf->read_perf);
    mStats.read_ios.evict(perf->read_ios);
    mStats.write_perf.evict(perf->write_perf);
    mStats.write_ios.evict(perf->write_ios);
    mStats.queue.evict(perf->queue);
}

bool disk_stats_monitor::detect(struct disk_perf* perf) {
    return ((double)perf->queue >= (double)mMean.queue + mSigma * (double)mStd.queue) &&
            ((double)perf->read_perf < (double)mMean.read_perf - mSigma * (double)mStd.read_perf) &&
            ((double)perf->write_perf < (double)mMean.write_perf - mSigma * (double)mStd.write_perf);
}

void disk_stats_monitor::update(struct disk_stats* stats) {
    struct disk_stats inc = get_inc_disk_stats(&mPrevious, stats);
    struct disk_perf perf = get_disk_perf(&inc);
    // Update internal data structures
    if (LIKELY(mValid)) {
        CHECK_EQ(mBuffer.size(), mWindow);

        if (UNLIKELY(detect(&perf))) {
            mStall = true;
            add_disk_stats(&inc, &mAccumulate);
            log_debug_disk_perf(&mMean, "stalled_mean");
            log_debug_disk_perf(&mStd, "stalled_std");
        } else {
            if (mStall) {
                struct disk_perf acc_perf = get_disk_perf(&mAccumulate);
                log_debug_disk_perf(&acc_perf, "stalled");
                log_event_disk_stats(&mAccumulate, "stalled");
                mStall = false;
                memset(&mAccumulate, 0, sizeof(mAccumulate));
            }
        }

        evict(&mBuffer.front());
        mBuffer.pop();
        add(&perf);
        mBuffer.push(perf);

        update_mean();
        update_std();

    } else { /* mValid == false */
        CHECK_LT(mBuffer.size(), mWindow);
        add(&perf);
        mBuffer.push(perf);
        if (mBuffer.size() == mWindow) {
            mValid = true;
            update_mean();
            update_std();
        }
    }

    mPrevious = *stats;
}

void disk_stats_monitor::update(void) {
    struct disk_stats curr;
    if (LIKELY(parse_disk_stats(DISK_STATS_PATH, &curr))) {
        update(&curr);
    }
}

static sp<IBatteryPropertiesRegistrar> get_battery_properties_service() {
    sp<IServiceManager> sm = defaultServiceManager();
    if (sm == NULL) return NULL;

    sp<IBinder> binder = sm->getService(String16("batteryproperties"));
    if (binder == NULL) return NULL;

    sp<IBatteryPropertiesRegistrar> battery_properties =
        interface_cast<IBatteryPropertiesRegistrar>(binder);

    return battery_properties;
}

static inline charger_stat_t is_charger_on(int64_t prop) {
    return (prop == BATTERY_STATUS_CHARGING || prop == BATTERY_STATUS_FULL) ?
        CHARGER_ON : CHARGER_OFF;
}

void storaged_t::batteryPropertiesChanged(struct BatteryProperties props) {
    mUidm.set_charger_state(is_charger_on(props.batteryStatus));
}

void storaged_t::init_battery_service() {
    if (!mConfig.proc_uid_io_available)
        return;

    battery_properties = get_battery_properties_service();
    if (battery_properties == NULL) {
        LOG_TO(SYSTEM, WARNING) << "failed to find batteryproperties service";
        return;
    }

    struct BatteryProperty val;
    battery_properties->getProperty(BATTERY_PROP_BATTERY_STATUS, &val);
    mUidm.init(is_charger_on(val.valueInt64));

    // register listener after init uid_monitor
    battery_properties->registerListener(this);
    IInterface::asBinder(battery_properties)->linkToDeath(this);
}

void storaged_t::binderDied(const wp<IBinder>& who) {
    if (battery_properties != NULL &&
        IInterface::asBinder(battery_properties) == who) {
        LOG_TO(SYSTEM, ERROR) << "batteryproperties service died, exiting";
        IPCThreadState::self()->stopProcess();
        exit(1);
    } else {
        LOG_TO(SYSTEM, ERROR) << "unknown service died";
    }
}

void storaged_t::report_storage_info() {
    storage_info->report();
}

/* storaged_t */
storaged_t::storaged_t(void) {
    if (access(MMC_DISK_STATS_PATH, R_OK) < 0 && access(SDA_DISK_STATS_PATH, R_OK) < 0) {
        mConfig.diskstats_available = false;
    } else {
        mConfig.diskstats_available = true;
    }

    mConfig.proc_uid_io_available = (access(UID_IO_STATS_PATH, R_OK) == 0);

    mConfig.periodic_chores_interval_unit =
        property_get_int32("ro.storaged.event.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT);

    mConfig.event_time_check_usec =
        property_get_int32("ro.storaged.event.perf_check", 0);

    mConfig.periodic_chores_interval_disk_stats_publish =
        property_get_int32("ro.storaged.disk_stats_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH);

    mConfig.periodic_chores_interval_uid_io =
        property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO);

    storage_info.reset(storage_info_t::get_storage_info());

    mStarttime = time(NULL);
}

void storaged_t::event(void) {
    if (mConfig.diskstats_available) {
        mDiskStats.update();
        mDsm.update();
        storage_info->refresh();
        if (mTimer && (mTimer % mConfig.periodic_chores_interval_disk_stats_publish) == 0) {
            mDiskStats.publish();
        }
    }

    if (mConfig.proc_uid_io_available && mTimer &&
            (mTimer % mConfig.periodic_chores_interval_uid_io) == 0) {
         mUidm.report();
    }

    mTimer += mConfig.periodic_chores_interval_unit;
}

void storaged_t::event_checked(void) {
    struct timespec start_ts, end_ts;
    bool check_time = true;

    if (mConfig.event_time_check_usec &&
        clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_ts) < 0) {
        check_time = false;
        static time_t state_a;
        IF_ALOG_RATELIMIT_LOCAL(300, &state_a) {
            PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
        }
    }

    event();

    if (mConfig.event_time_check_usec && check_time) {
        if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_ts) < 0) {
            static time_t state_b;
            IF_ALOG_RATELIMIT_LOCAL(300, &state_b) {
                PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
            }
            return;
        }
        int64_t cost = (end_ts.tv_sec - start_ts.tv_sec) * SEC_TO_USEC +
                       (end_ts.tv_nsec - start_ts.tv_nsec) / USEC_TO_NSEC;
        if (cost > mConfig.event_time_check_usec) {
            LOG_TO(SYSTEM, ERROR)
                << "event loop spent " << cost << " usec, threshold "
                << mConfig.event_time_check_usec << " usec";
        }
    }
}
