/*
 * Copyright (C) 2015 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 "Benchmark.h"
#include "BenchmarkGen.h"
#include "VolumeManager.h"

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

#include <cutils/iosched_policy.h>
#include <hardware_legacy/power.h>
#include <private/android_filesystem_config.h>

#include <thread>

#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

using android::base::ReadFileToString;
using android::base::WriteStringToFile;

namespace android {
namespace vold {

// Benchmark currently uses chdir(), which means we can only
// safely run one at a time.
static std::mutex kBenchmarkLock;

static const char* kWakeLock = "Benchmark";

// Reasonable cards are able to complete the create/run stages
// in under 20 seconds.
constexpr auto kTimeout = 20s;

// RAII class for boosting device performance during benchmarks.
class PerformanceBoost {
private:
    int orig_prio;
    int orig_ioprio;
    IoSchedClass orig_clazz;

public:
    PerformanceBoost() {
        errno = 0;
        orig_prio = getpriority(PRIO_PROCESS, 0);
        if (errno != 0) {
            PLOG(WARNING) << "Failed to getpriority";
            orig_prio = 0;
        }
        if (setpriority(PRIO_PROCESS, 0, -10) != 0) {
            PLOG(WARNING) << "Failed to setpriority";
        }
        if (android_get_ioprio(0, &orig_clazz, &orig_ioprio)) {
            PLOG(WARNING) << "Failed to android_get_ioprio";
            orig_ioprio = 0;
            orig_clazz = IoSchedClass_NONE;
        }
        if (android_set_ioprio(0, IoSchedClass_RT, 0)) {
            PLOG(WARNING) << "Failed to android_set_ioprio";
        }
    }

    ~PerformanceBoost() {
        if (android_set_ioprio(0, orig_clazz, orig_ioprio)) {
            PLOG(WARNING) << "Failed to android_set_ioprio";
        }
        if (setpriority(PRIO_PROCESS, 0, orig_prio) != 0) {
            PLOG(WARNING) << "Failed to setpriority";
        }
    }
};

static status_t benchmarkInternal(const std::string& rootPath,
        const android::sp<android::os::IVoldTaskListener>& listener,
        android::os::PersistableBundle* extras) {
    status_t res = 0;

    auto path = rootPath;
    path += "/misc";
    if (android::vold::PrepareDir(path, 01771, AID_SYSTEM, AID_MISC)) {
        return -1;
    }
    path += "/vold";
    if (android::vold::PrepareDir(path, 0700, AID_ROOT, AID_ROOT)) {
        return -1;
    }
    path += "/bench";
    if (android::vold::PrepareDir(path, 0700, AID_ROOT, AID_ROOT)) {
        return -1;
    }

    char orig_cwd[PATH_MAX];
    if (getcwd(orig_cwd, PATH_MAX) == NULL) {
        PLOG(ERROR) << "Failed getcwd";
        return -1;
    }
    if (chdir(path.c_str()) != 0) {
        PLOG(ERROR) << "Failed chdir";
        return -1;
    }

    sync();

    extras->putString(String16("path"), String16(path.c_str()));
    extras->putString(String16("ident"), String16(BenchmarkIdent().c_str()));

    // Always create
    {
        android::base::Timer timer;
        LOG(INFO) << "Creating " << path;
        res |= BenchmarkCreate([&](int progress) -> bool {
            if (listener) {
                listener->onStatus(progress, *extras);
            }
            return (timer.duration() < kTimeout);
        });
        sync();
        if (res == OK) extras->putLong(String16("create"), timer.duration().count());
    }

    // Only drop when we haven't aborted
    if (res == OK) {
        android::base::Timer timer;
        LOG(VERBOSE) << "Before drop_caches";
        if (!WriteStringToFile("3", "/proc/sys/vm/drop_caches")) {
            PLOG(ERROR) << "Failed to drop_caches";
            res = -1;
        }
        LOG(VERBOSE) << "After drop_caches";
        sync();
        if (res == OK) extras->putLong(String16("drop"), timer.duration().count());
    }

    // Only run when we haven't aborted
    if (res == OK) {
        android::base::Timer timer;
        LOG(INFO) << "Running " << path;
        res |= BenchmarkRun([&](int progress) -> bool {
            if (listener) {
                listener->onStatus(progress, *extras);
            }
            return (timer.duration() < kTimeout);
        });
        sync();
        if (res == OK) extras->putLong(String16("run"), timer.duration().count());
    }

    // Always destroy
    {
        android::base::Timer timer;
        LOG(INFO) << "Destroying " << path;
        res |= BenchmarkDestroy();
        sync();
        if (res == OK) extras->putLong(String16("destroy"), timer.duration().count());
    }

    if (chdir(orig_cwd) != 0) {
        PLOG(ERROR) << "Failed to chdir";
        return -1;
    }

    return res;
}

void Benchmark(const std::string& path,
        const android::sp<android::os::IVoldTaskListener>& listener) {
    std::lock_guard<std::mutex> lock(kBenchmarkLock);
    acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock);

    PerformanceBoost boost;
    android::os::PersistableBundle extras;

    status_t res = benchmarkInternal(path, listener, &extras);
    if (listener) {
        listener->onFinished(res, extras);
    }

    release_wake_lock(kWakeLock);
}

}  // namespace vold
}  // namespace android
