/*
 * 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 <deque>
#include <fcntl.h>
#include <random>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#include <gtest/gtest.h>

#include <storaged.h>               // data structures
#include <storaged_utils.h>         // functions to test

#define MMC_DISK_STATS_PATH "/sys/block/mmcblk0/stat"
#define SDA_DISK_STATS_PATH "/sys/block/sda/stat"

static void pause(uint32_t sec) {
    const char* path = "/cache/test";
    int fd = open(path, O_WRONLY | O_CREAT, 0600);
    ASSERT_LT(-1, fd);
    char buffer[2048];
    memset(buffer, 1, sizeof(buffer));
    int loop_size = 100;
    for (int i = 0; i < loop_size; ++i) {
        ASSERT_EQ(2048, write(fd, buffer, sizeof(buffer)));
    }
    fsync(fd);
    close(fd);

    fd = open(path, O_RDONLY);
    ASSERT_LT(-1, fd);
    for (int i = 0; i < loop_size; ++i) {
        ASSERT_EQ(2048, read(fd, buffer, sizeof(buffer)));
    }
    close(fd);

    sleep(sec);
}

// the return values of the tested functions should be the expected ones
const char* DISK_STATS_PATH;
TEST(storaged_test, retvals) {
    struct disk_stats stats;
    memset(&stats, 0, sizeof(struct disk_stats));

    if (access(MMC_DISK_STATS_PATH, R_OK) >= 0) {
        DISK_STATS_PATH = MMC_DISK_STATS_PATH;
    } else if (access(SDA_DISK_STATS_PATH, R_OK) >= 0) {
        DISK_STATS_PATH = SDA_DISK_STATS_PATH;
    } else {
        return;
    }

    EXPECT_TRUE(parse_disk_stats(DISK_STATS_PATH, &stats));

    struct disk_stats old_stats;
    memset(&old_stats, 0, sizeof(struct disk_stats));
    old_stats = stats;

    const char wrong_path[] = "/this/is/wrong";
    EXPECT_FALSE(parse_disk_stats(wrong_path, &stats));

    // reading a wrong path should not damage the output structure
    EXPECT_EQ(0, memcmp(&stats, &old_stats, sizeof(disk_stats)));
}

TEST(storaged_test, disk_stats) {
    struct disk_stats stats;
    memset(&stats, 0, sizeof(struct disk_stats));

    ASSERT_TRUE(parse_disk_stats(DISK_STATS_PATH, &stats));

    // every entry of stats (except io_in_flight) should all be greater than 0
    for (uint i = 0; i < DISK_STATS_SIZE; ++i) {
        if (i == 8) continue; // skip io_in_flight which can be 0
        EXPECT_LT((uint64_t)0, *((uint64_t*)&stats + i));
    }

    // accumulation of the increments should be the same with the overall increment
    struct disk_stats base, tmp, curr, acc, inc[5];
    memset(&base, 0, sizeof(struct disk_stats));
    memset(&tmp, 0, sizeof(struct disk_stats));
    memset(&acc, 0, sizeof(struct disk_stats));

    for (uint i = 0; i < 5; ++i) {
        ASSERT_TRUE(parse_disk_stats(DISK_STATS_PATH, &curr));
        if (i == 0) {
            base = curr;
            tmp = curr;
            sleep(5);
            continue;
        }
        inc[i] = get_inc_disk_stats(&tmp, &curr);
        add_disk_stats(&inc[i], &acc);
        tmp = curr;
        pause(5);
    }
    struct disk_stats overall_inc;
    memset(&overall_inc, 0, sizeof(disk_stats));
    overall_inc= get_inc_disk_stats(&base, &curr);

    for (uint i = 0; i < DISK_STATS_SIZE; ++i) {
        if (i == 8) continue; // skip io_in_flight which can be 0
        EXPECT_EQ(*((uint64_t*)&overall_inc + i), *((uint64_t*)&acc + i));
    }
}

static double mean(std::deque<uint32_t> nums) {
    double sum = 0.0;
    for (uint32_t i : nums) {
    sum += i;
    }
    return sum / nums.size();
}

static double standard_deviation(std::deque<uint32_t> nums) {
    double sum = 0.0;
    double avg = mean(nums);
    for (uint32_t i : nums) {
    sum += ((double)i - avg) * ((double)i - avg);
    }
    return sqrt(sum / nums.size());
}

TEST(storaged_test, stream_stats) {
    // 100 random numbers
    std::vector<uint32_t> data = {8147,9058,1270,9134,6324,975,2785,5469,9575,9649,1576,9706,9572,4854,8003,1419,4218,9157,7922,9595,6557,357,8491,9340,6787,7577,7431,3922,6555,1712,7060,318,2769,462,971,8235,6948,3171,9502,344,4387,3816,7655,7952,1869,4898,4456,6463,7094,7547,2760,6797,6551,1626,1190,4984,9597,3404,5853,2238,7513,2551,5060,6991,8909,9593,5472,1386,1493,2575,8407,2543,8143,2435,9293,3500,1966,2511,6160,4733,3517,8308,5853,5497,9172,2858,7572,7537,3804,5678,759,540,5308,7792,9340,1299,5688,4694,119,3371};
    std::deque<uint32_t> test_data;
    stream_stats sstats;
    for (uint32_t i : data) {
        test_data.push_back(i);
        sstats.add(i);

        EXPECT_EQ((int)standard_deviation(test_data), (int)sstats.get_std());
        EXPECT_EQ((int)mean(test_data), (int)sstats.get_mean());
    }

    for (uint32_t i : data) {
        test_data.pop_front();
        sstats.evict(i);

        EXPECT_EQ((int)standard_deviation(test_data), (int)sstats.get_std());
        EXPECT_EQ((int)mean(test_data), (int)sstats.get_mean());
    }

    // some real data
    std::vector<uint32_t> another_data = {113875,81620,103145,28327,86855,207414,96526,52567,28553,250311};
    test_data.clear();
    uint32_t window_size = 2;
    uint32_t idx;
    stream_stats sstats1;
    for (idx = 0; idx < window_size; ++idx) {
        test_data.push_back(another_data[idx]);
        sstats1.add(another_data[idx]);
    }
    EXPECT_EQ((int)standard_deviation(test_data), (int)sstats1.get_std());
    EXPECT_EQ((int)mean(test_data), (int)sstats1.get_mean());
    for (;idx < another_data.size(); ++idx) {
        test_data.pop_front();
        sstats1.evict(another_data[idx - window_size]);
        test_data.push_back(another_data[idx]);
        sstats1.add(another_data[idx]);
        EXPECT_EQ((int)standard_deviation(test_data), (int)sstats1.get_std());
        EXPECT_EQ((int)mean(test_data), (int)sstats1.get_mean());
    }
}

static struct disk_perf disk_perf_multiply(struct disk_perf perf, double mul) {
    struct disk_perf retval;
    retval.read_perf = (double)perf.read_perf * mul;
    retval.read_ios = (double)perf.read_ios * mul;
    retval.write_perf = (double)perf.write_perf * mul;
    retval.write_ios = (double)perf.write_ios * mul;
    retval.queue = (double)perf.queue * mul;

    return retval;
}

static struct disk_stats disk_stats_add(struct disk_stats stats1, struct disk_stats stats2) {
    struct disk_stats retval;
    retval.read_ios = stats1.read_ios + stats2.read_ios;
    retval.read_merges = stats1.read_merges + stats2.read_merges;
    retval.read_sectors = stats1.read_sectors + stats2.read_sectors;
    retval.read_ticks = stats1.read_ticks + stats2.read_ticks;
    retval.write_ios = stats1.write_ios + stats2.write_ios;
    retval.write_merges = stats1.write_merges + stats2.write_merges;
    retval.write_sectors = stats1.write_sectors + stats2.write_sectors;
    retval.write_ticks = stats1.write_ticks + stats2.write_ticks;
    retval.io_in_flight = stats1.io_in_flight + stats2.io_in_flight;
    retval.io_ticks = stats1.io_ticks + stats2.io_ticks;
    retval.io_in_queue = stats1.io_in_queue + stats2.io_in_queue;
    retval.end_time = stats1.end_time + stats2.end_time;

    return retval;
}

TEST(storaged_test, disk_stats_monitor) {
    // asserting that there is one file for diskstats
    ASSERT_TRUE(access(MMC_DISK_STATS_PATH, R_OK) >= 0 || access(SDA_DISK_STATS_PATH, R_OK) >= 0);
    // testing if detect() will return the right value
    disk_stats_monitor dsm_detect;
    // feed monitor with constant perf data for io perf baseline
    // using constant perf is reasonable since the functionality of stream_stats
    // has already been tested
    struct disk_perf norm_perf = {
        .read_perf = 10 * 1024,
        .read_ios = 50,
        .write_perf = 5 * 1024,
        .write_ios = 25,
        .queue = 5
    };

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> rand(0.8, 1.2);

    for (uint i = 0; i < dsm_detect.mWindow; ++i) {
        struct disk_perf perf = disk_perf_multiply(norm_perf, rand(gen));

        dsm_detect.add(&perf);
        dsm_detect.mBuffer.push(perf);
        EXPECT_EQ(dsm_detect.mBuffer.size(), (uint64_t)i + 1);
    }

    dsm_detect.mValid = true;
    dsm_detect.update_mean();
    dsm_detect.update_std();

    for (double i = 0; i < 2 * dsm_detect.mSigma; i += 0.5) {
        struct disk_perf test_perf;
        struct disk_perf test_mean = dsm_detect.mMean;
        struct disk_perf test_std = dsm_detect.mStd;

        test_perf.read_perf = (double)test_mean.read_perf - i * test_std.read_perf;
        test_perf.read_ios = (double)test_mean.read_ios - i * test_std.read_ios;
        test_perf.write_perf = (double)test_mean.write_perf - i * test_std.write_perf;
        test_perf.write_ios = (double)test_mean.write_ios - i * test_std.write_ios;
        test_perf.queue = (double)test_mean.queue + i * test_std.queue;

        EXPECT_EQ((i > dsm_detect.mSigma), dsm_detect.detect(&test_perf));
    }

    // testing if stalled disk_stats can be correctly accumulated in the monitor
    disk_stats_monitor dsm_acc;
    struct disk_stats norm_inc = {
        .read_ios = 200,
        .read_merges = 0,
        .read_sectors = 200,
        .read_ticks = 200,
        .write_ios = 100,
        .write_merges = 0,
        .write_sectors = 100,
        .write_ticks = 100,
        .io_in_flight = 0,
        .io_ticks = 600,
        .io_in_queue = 300,
        .start_time = 0,
        .end_time = 100,
        .counter = 0,
        .io_avg = 0
    };

    struct disk_stats stall_inc = {
        .read_ios = 200,
        .read_merges = 0,
        .read_sectors = 20,
        .read_ticks = 200,
        .write_ios = 100,
        .write_merges = 0,
        .write_sectors = 10,
        .write_ticks = 100,
        .io_in_flight = 0,
        .io_ticks = 600,
        .io_in_queue = 1200,
        .start_time = 0,
        .end_time = 100,
        .counter = 0,
        .io_avg = 0
    };

    struct disk_stats stats_base;
    memset(&stats_base, 0, sizeof(stats_base));

    int loop_size = 100;
    for (int i = 0; i < loop_size; ++i) {
        stats_base = disk_stats_add(stats_base, norm_inc);
        dsm_acc.update(&stats_base);
        EXPECT_EQ(dsm_acc.mValid, (uint32_t)(i + 1) >= dsm_acc.mWindow);
        EXPECT_FALSE(dsm_acc.mStall);
    }

    stats_base = disk_stats_add(stats_base, stall_inc);
    dsm_acc.update(&stats_base);
    EXPECT_TRUE(dsm_acc.mValid);
    EXPECT_TRUE(dsm_acc.mStall);

    for (int i = 0; i < 10; ++i) {
        stats_base = disk_stats_add(stats_base, norm_inc);
        dsm_acc.update(&stats_base);
        EXPECT_TRUE(dsm_acc.mValid);
        EXPECT_FALSE(dsm_acc.mStall);
    }
}

static void expect_increasing(struct disk_stats stats1, struct disk_stats stats2) {
    EXPECT_LE(stats1.read_ios, stats2.read_ios);
    EXPECT_LE(stats1.read_merges, stats2.read_merges);
    EXPECT_LE(stats1.read_sectors, stats2.read_sectors);
    EXPECT_LE(stats1.read_ticks, stats2.read_ticks);

    EXPECT_LE(stats1.write_ios, stats2.write_ios);
    EXPECT_LE(stats1.write_merges, stats2.write_merges);
    EXPECT_LE(stats1.write_sectors, stats2.write_sectors);
    EXPECT_LE(stats1.write_ticks, stats2.write_ticks);

    EXPECT_LE(stats1.io_ticks, stats2.io_ticks);
    EXPECT_LE(stats1.io_in_queue, stats2.io_in_queue);
}

#define TEST_LOOPS 20
TEST(storaged_test, disk_stats_publisher) {
    // asserting that there is one file for diskstats
    ASSERT_TRUE(access(MMC_DISK_STATS_PATH, R_OK) >= 0 || access(SDA_DISK_STATS_PATH, R_OK) >= 0);
    disk_stats_publisher dsp;
    struct disk_stats prev;
    memset(&prev, 0, sizeof(prev));

    for (int i = 0; i < TEST_LOOPS; ++i) {
        dsp.update();
        expect_increasing(prev, dsp.mPrevious);
        prev = dsp.mPrevious;
        pause(10);
    }
}

