#!/usr/bin/python3
#
# Copyright (c) KylinSoft Co., Ltd. [2026].All rights reserved.

import sys
import re
import matplotlib.pyplot as plt

def parse_log(filename):
    fs_ts, fs_latency = [], []
    q2c_ts, q2c_latency = [], []
    d2c_ts, d2c_latency = [], []

    base_ts = None  # 第一条日志时间戳（全局时间零点）

    with open(filename, 'r') as f:
        for line in f:
            m = re.search(r'timestamp:\s+(\d+).*fs_latency:\s+([\d.]+)\s+us', line)
            if m:
                ts = int(m.group(1))
                if base_ts is None:
                    base_ts = ts
                fs_ts.append(ts)
                fs_latency.append(float(m.group(2)))
                continue

            m = re.search(r'timestamp:\s+(\d+).*q2c:\s+([\d.]+)\s+us', line)
            if m:
                ts = int(m.group(1))
                if base_ts is None:
                    base_ts = ts
                q2c_ts.append(ts)
                q2c_latency.append(float(m.group(2)))
                continue

            m = re.search(r'timestamp:\s+(\d+).*d2c:\s+([\d.]+)\s+us', line)
            if m:
                ts = int(m.group(1))
                if base_ts is None:
                    base_ts = ts
                d2c_ts.append(ts)
                d2c_latency.append(float(m.group(2)))

    return (
        base_ts,
        fs_ts, fs_latency,
        q2c_ts, q2c_latency,
        d2c_ts, d2c_latency
    )


def ns_to_sec(ts_list, base):
    return [(t - base) / 1e9 for t in ts_list]


def plot_all_latency(
    fs_t, fs_lat,
    q2c_t, q2c_lat,
    d2c_t, d2c_lat
):
    plt.figure(figsize=(10, 6))

    if fs_t:
        plt.plot(
            fs_t,
            fs_lat,
            marker='.',
            linewidth=0.2,
            markersize=1,
            label="fs_latency (us)"
        )

    if q2c_t:
        plt.plot(
            q2c_t,
            q2c_lat,
            marker='.',
            linewidth=0.2,
            markersize=1,
            label="q2c (us)"
        )

    if d2c_t:
        plt.plot(
            d2c_t,
            d2c_lat,
            marker='.',
            linewidth=0.2,
            markersize=1,
            label="d2c (us)"
        )

    plt.xlabel("Time (seconds)")
    plt.ylabel("Latency (us)")
    plt.title("I/O Latency (Filesystem + Block Layer)")
    plt.legend()
    plt.grid(True)
    plt.tight_layout()
    plt.savefig("io_latency.svg", format="svg")
    plt.close()


def main():
    if len(sys.argv) != 2:
        print(f"Usage: iolatency_plot io_latency_*.log")
        sys.exit(1)

    filename = sys.argv[1]

    (
        base_ts,
        fs_ts, fs_latency,
        q2c_ts, q2c_latency,
        d2c_ts, d2c_latency
    ) = parse_log(filename)

    if base_ts is None:
        print("No valid latency records found")
        sys.exit(1)

    fs_t_sec  = ns_to_sec(fs_ts, base_ts)
    q2c_t_sec = ns_to_sec(q2c_ts, base_ts)
    d2c_t_sec = ns_to_sec(d2c_ts, base_ts)

    plot_all_latency(
        fs_t_sec, fs_latency,
        q2c_t_sec, q2c_latency,
        d2c_t_sec, d2c_latency
    )

    print("SVG file generated:")
    print("  io_latency.svg")


if __name__ == "__main__":
    main()

