import tempfile
import time
import pandas as pd
import pickle

from imc_utils.pps_e36311a import PPS_E36311A
from imc_utils.build_config.cortex_m33 import BuildConfigM33
from imc_utils.build_config.test_env import TestEnv
import imc_utils.serial_device
from imc_utils.serial_watch import SerialWatcher

WORKSPACE_ROOT = "/home/ybkim/workspace/imc/imc_freertos_app_m33"
NVM_RESET_BIN = f"{WORKSPACE_ROOT}/imc/utils/nvm_reset.elf"
OPENOCD_SCRIPT = f"{WORKSPACE_ROOT}/imc_freertos_app_m33.cfg"

def main():
    pps = PPS_E36311A()
    config = get_default_build_config()

    benchmarks = [
        "vBasicMath", "vCrc", "vFFT", "vSha", "vStringSearch", "vMatMul", "vConv2d", "vAes"
    ]

    for benchmark in benchmarks:
        config.bench_name = benchmark
        config.insert_compiler_checkpoints = False
        config.use_checkpoint_pass_counter = False
        config.use_checkpoint_voltage_check = False
        config.checkpoint_pass_count = 1000
        config.bench_infinite_loop = True
        config.split_loop = True

        pps.set_voltage(3.3, 1)
        pps.set_current(0.1, 1)
        pps.output_on(1)

        env = TestEnv(WORKSPACE_ROOT, NVM_RESET_BIN, OPENOCD_SCRIPT)

        with tempfile.TemporaryDirectory() as build_dir:
            binary = env.build_binary(config, build_dir)
            env.clear_nvm_and_load_binary(binary, resume=False)
        
        # pps.set_current(0.015, 1)
        # time.sleep(1)

        env.resume_board(terminate=True)
        total_iterations = 2
        records = SerialWatcher(benchmark, total_iterations).run()
        # records = measure_execution_time(benchmark, total_iterations)
        df = pd.DataFrame(records)
        save_records(benchmark, df)
        print(df)


def get_default_build_config():
    config = BuildConfigM33()
    config.bench_name = "vBasicMath"
    config.insert_compiler_checkpoints = True
    config.enable_extension = True
    config.use_checkpoint_pass_counter = False
    config.use_checkpoint_voltage_check = True
    config.bench_infinite_loop = True
    config.checkpoint_pass_count = 100
    config.print_recovery_message = True
    return config


def save_records(bench_name, df):
    with open(f"output/{bench_name}.pickle", "wb") as f:
        pickle.dump(df, f)


if __name__ == "__main__":
    main()
