#!/usr/bin/env python3
#
# Copyright (C) 2018 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.
#

import os
import statistics
import subprocess
import sys
import tempfile
import time

# Make sure environment is setup, otherwise "adb" module is not available.
if os.getenv("ANDROID_BUILD_TOP") is None:
    print("Run source/lunch before running " + sys.argv[0])
    sys.exit()

import adb

def lock_min(device):
    device.shell_nocheck(["""
        for x in /sys/devices/system/cpu/cpu?/cpufreq; do
            echo userspace > $x/scaling_governor
            cat $x/scaling_min_freq > $x/scaling_setspeed
        done
    """])

def lock_max(device):
    device.shell_nocheck(["""
        for x in /sys/devices/system/cpu/cpu?/cpufreq; do
            echo userspace > $x/scaling_governor
            cat $x/scaling_max_freq > $x/scaling_setspeed
        done
    """])

def unlock(device):
    device.shell_nocheck(["""
        for x in /sys/devices/system/cpu/cpu?/cpufreq; do
            echo ondemand > $x/scaling_governor
            echo sched > $x/scaling_governor
            echo schedutil > $x/scaling_governor
        done
    """])

def harmonic_mean(xs):
    return 1.0 / statistics.mean([1.0 / x for x in xs])

def analyze(name, speeds):
    median = statistics.median(speeds)
    mean = harmonic_mean(speeds)
    stddev = statistics.stdev(speeds)
    msg = "%s: %d runs: median %.2f MiB/s, mean %.2f MiB/s, stddev: %.2f MiB/s"
    print(msg % (name, len(speeds), median, mean, stddev))

def benchmark_sink(device=None, size_mb=100):
    if device == None:
        device = adb.get_device()

    speeds = list()
    cmd = device.adb_cmd + ["raw", "sink:%d" % (size_mb * 1024 * 1024)]

    with tempfile.TemporaryFile() as tmpfile:
        tmpfile.truncate(size_mb * 1024 * 1024)

        for _ in range(0, 10):
            tmpfile.seek(0)
            begin = time.time()
            subprocess.check_call(cmd, stdin=tmpfile)
            end = time.time()
            speeds.append(size_mb / float(end - begin))

    analyze("sink %dMiB" % size_mb, speeds)

def benchmark_source(device=None, size_mb=100):
    if device == None:
        device = adb.get_device()

    speeds = list()
    cmd = device.adb_cmd + ["raw", "source:%d" % (size_mb * 1024 * 1024)]

    with open(os.devnull, 'w') as devnull:
        for _ in range(0, 10):
            begin = time.time()
            subprocess.check_call(cmd, stdout=devnull)
            end = time.time()
            speeds.append(size_mb / float(end - begin))

    analyze("source %dMiB" % size_mb, speeds)

def benchmark_push(device=None, file_size_mb=100):
    if device == None:
        device = adb.get_device()

    remote_path = "/dev/null"
    local_path = "/tmp/adb_benchmark_temp"

    with open(local_path, "wb") as f:
        f.truncate(file_size_mb * 1024 * 1024)

    speeds = list()
    for _ in range(0, 10):
        begin = time.time()
        device.push(local=local_path, remote=remote_path)
        end = time.time()
        speeds.append(file_size_mb / float(end - begin))

    analyze("push %dMiB" % file_size_mb, speeds)

def benchmark_pull(device=None, file_size_mb=100):
    if device == None:
        device = adb.get_device()

    remote_path = "/data/local/tmp/adb_benchmark_temp"
    local_path = "/tmp/adb_benchmark_temp"

    device.shell(["dd", "if=/dev/zero", "of=" + remote_path, "bs=1m",
                  "count=" + str(file_size_mb)])
    speeds = list()
    for _ in range(0, 10):
        begin = time.time()
        device.pull(remote=remote_path, local=local_path)
        end = time.time()
        speeds.append(file_size_mb / float(end - begin))

    analyze("pull %dMiB" % file_size_mb, speeds)

def benchmark_shell(device=None, file_size_mb=100):
    if device == None:
        device = adb.get_device()

    speeds = list()
    for _ in range(0, 10):
        begin = time.time()
        device.shell(["dd", "if=/dev/zero", "bs=1m",
                      "count=" + str(file_size_mb)])
        end = time.time()
        speeds.append(file_size_mb / float(end - begin))

    analyze("shell %dMiB" % file_size_mb, speeds)

def main():
    device = adb.get_device()
    unlock(device)
    benchmark_sink(device)
    benchmark_source(device)
    benchmark_push(device)
    benchmark_pull(device)

if __name__ == "__main__":
    main()
