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

#include <stdint.h>
#include <stdlib.h>

#include <sstream>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <log/log_event_list.h>

#include "storaged.h"
#include "storaged_diskstats.h"

namespace {

using android::sp;
using android::hardware::health::V2_0::DiskStats;
using android::hardware::health::V2_0::IHealth;
using android::hardware::health::V2_0::Result;
using android::hardware::health::V2_0::toString;

#ifdef DEBUG
void log_debug_disk_perf(struct disk_perf* perf, const char* type) {
    // skip if the input structure are all zeros
    if (perf == NULL || perf->is_zero()) return;

    LOG(INFO) << "disk_perf " << type << " rd: " << perf->read_perf << " kbps, " << perf->read_ios
              << " iops"
              << " wr: " << perf->write_perf << " kbps, " << perf->write_ios << " iops"
              << " q: " << perf->queue;
}
#else
void log_debug_disk_perf(struct disk_perf* perf, const char* type) {}
#endif

void log_event_disk_stats(struct disk_stats* stats, const char* type) {
    // skip if the input structure are all zeros
    if (stats == NULL || stats->is_zero()) return;

    android_log_event_list(EVENTLOGTAG_DISKSTATS)
        << type << stats->start_time << stats->end_time
        << stats->read_ios << stats->read_merges
        << stats->read_sectors << stats->read_ticks
        << stats->write_ios << stats->write_merges
        << stats->write_sectors << stats->write_ticks
        << (uint64_t)stats->io_avg << stats->io_ticks << stats->io_in_queue
        << LOG_ID_EVENTS;
}

} // namespace

bool get_time(struct timespec* ts) {
    // Use monotonic to exclude suspend time so that we measure IO bytes/sec
    // when system is running.
    int ret = clock_gettime(CLOCK_MONOTONIC, ts);
    if (ret < 0) {
        PLOG(ERROR) << "clock_gettime() failed";
        return false;
    }
    return true;
}

void init_disk_stats_other(const struct timespec& ts, struct disk_stats* stats) {
    stats->start_time = 0;
    stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC + ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
    stats->counter = 1;
    stats->io_avg = (double)stats->io_in_flight;
}

bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) {
    // Get time
    struct timespec ts;
    if (!get_time(&ts)) {
        return false;
    }

    std::string buffer;
    if (!android::base::ReadFileToString(disk_stats_path, &buffer)) {
        PLOG(ERROR) << disk_stats_path << ": ReadFileToString failed.";
        return false;
    }

    // Regular diskstats entries
    std::stringstream ss(buffer);
    for (uint i = 0; i < DISK_STATS_SIZE; ++i) {
        ss >> *((uint64_t*)stats + i);
    }
    // Other entries
    init_disk_stats_other(ts, stats);
    return true;
}

void convert_hal_disk_stats(struct disk_stats* dst, const DiskStats& src) {
    dst->read_ios = src.reads;
    dst->read_merges = src.readMerges;
    dst->read_sectors = src.readSectors;
    dst->read_ticks = src.readTicks;
    dst->write_ios = src.writes;
    dst->write_merges = src.writeMerges;
    dst->write_sectors = src.writeSectors;
    dst->write_ticks = src.writeTicks;
    dst->io_in_flight = src.ioInFlight;
    dst->io_ticks = src.ioTicks;
    dst->io_in_queue = src.ioInQueue;
}

bool get_disk_stats_from_health_hal(const sp<IHealth>& service, struct disk_stats* stats) {
    struct timespec ts;
    if (!get_time(&ts)) {
        return false;
    }

    bool success = false;
    auto ret = service->getDiskStats([&success, stats](auto result, const auto& halStats) {
        if (result == Result::NOT_SUPPORTED) {
            LOG(DEBUG) << "getDiskStats is not supported on health HAL.";
            return;
        }
        if (result != Result::SUCCESS || halStats.size() == 0) {
            LOG(ERROR) << "getDiskStats failed with result " << toString(result) << " and size "
                       << halStats.size();
            return;
        }

        convert_hal_disk_stats(stats, halStats[0]);
        success = true;
    });

    if (!ret.isOk()) {
        LOG(ERROR) << "getDiskStats failed with " << ret.description();
        return false;
    }

    if (!success) {
        return false;
    }

    init_disk_stats_other(ts, stats);
    return true;
}

struct disk_perf get_disk_perf(struct disk_stats* stats)
{
    struct disk_perf perf = {};

    if (stats->io_ticks) {
        if (stats->read_ticks) {
            unsigned long long divisor = stats->read_ticks * stats->io_ticks;
            perf.read_perf = ((unsigned long long)SECTOR_SIZE *
                              stats->read_sectors * stats->io_in_queue +
                              (divisor >> 1)) / divisor;
            perf.read_ios = ((unsigned long long)SEC_TO_MSEC *
                             stats->read_ios * stats->io_in_queue +
                             (divisor >> 1)) / divisor;
        }
        if (stats->write_ticks) {
            unsigned long long divisor = stats->write_ticks * stats->io_ticks;
            perf.write_perf = ((unsigned long long)SECTOR_SIZE *
                               stats->write_sectors * stats->io_in_queue +
                               (divisor >> 1)) / divisor;
            perf.write_ios = ((unsigned long long)SEC_TO_MSEC *
                              stats->write_ios * stats->io_in_queue +
                              (divisor >> 1)) / divisor;
        }
        perf.queue = (stats->io_in_queue + (stats->io_ticks >> 1)) /
                     stats->io_ticks;
    }
    return perf;
}

void get_inc_disk_stats(const struct disk_stats* prev, const struct disk_stats* curr,
                        struct disk_stats* inc)
{
    *inc = *curr - *prev;
    inc->start_time = prev->end_time;
    inc->end_time = curr->end_time;
    inc->io_avg = curr->io_avg;
    inc->counter = 1;
}

// Add src to dst
void add_disk_stats(struct disk_stats* src, struct disk_stats* dst)
{
    if (dst->end_time != 0 && dst->end_time != src->start_time) {
        LOG(WARNING) << "Two dis-continuous periods of diskstats"
                     << " are added. dst end with " << dst->end_time << ", src start with "
                     << src->start_time;
    }

    *dst += *src;

    dst->io_in_flight = src->io_in_flight;
    if (dst->counter + src->counter) {
        dst->io_avg =
            ((dst->io_avg * dst->counter) + (src->io_avg * src->counter)) /
            (dst->counter + src->counter);
    }
    dst->counter += src->counter;
    dst->end_time = src->end_time;
    if (dst->start_time == 0) {
        dst->start_time = src->start_time;
    }
}

/* 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* curr)
{
    disk_stats inc;
    get_inc_disk_stats(&mPrevious, curr, &inc);
    add_disk_stats(&inc, &mAccumulate_pub);

    struct disk_perf perf = get_disk_perf(&inc);
    log_debug_disk_perf(&perf, "regular");

    add(&perf);
    mBuffer.push(perf);
    if (mBuffer.size() > mWindow) {
        evict(&mBuffer.front());
        mBuffer.pop();
        mValid = true;
    }

    // Update internal data structures
    if (LIKELY(mValid)) {
        CHECK_EQ(mBuffer.size(), mWindow);
        update_mean();
        update_std();
        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));
            }
        }
    }

    mPrevious = *curr;
}

void disk_stats_monitor::update() {
    disk_stats curr;
    if (mHealth != nullptr) {
        if (!get_disk_stats_from_health_hal(mHealth, &curr)) {
            return;
        }
    } else {
        if (!parse_disk_stats(DISK_STATS_PATH, &curr)) {
            return;
        }
    }

    update(&curr);
}

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