# -*- coding: utf-8 -*-
"""
第4轮: 图 ID 枚举 + 图名 RPC 试探
==================================
第3轮已标定: "Graph name does not exist" = 图不存在; "No points exist" =
图存在但未求解。get_magnetic_graph_point 的 graph 参数可传数字 ID (variant),
故枚举 ID 0..N 找出全部存在的图; 再试几个未封装的 RPC 方法名拿 ID→名字映射;
拿不到名字就求解后读全部波形, 按量级特征辨认轴向力。

用法: python axial_probe3.py [--quit] [--max-id N]
"""
import json
import os
import sys
import time

BASE = os.path.dirname(os.path.abspath(__file__))
MOT_SRC = os.path.join(BASE, "MARS-12S10P_SSSR_D76-C150_V5.0-0819.mot")
OUT_DIR = os.path.join(BASE, "output_motorcad")

NAME_RPCS = ["GetMagneticGraphName", "GetMagneticGraphTitle", "GetGraphName",
             "GetMagneticGraphInfo", "GetMagneticGraphCount",
             "GetMagneticGraphNames", "GetMagneticGraphYAxisTitle"]


def classify(mc, graph):
    try:
        x, y = mc.get_magnetic_graph_point(graph, 0)
        return "OK", (x, y)
    except Exception as e:
        msg = str(e)
        if "does not exist" in msg:
            return "ABSENT", None
        if "No points exist" in msg:
            return "EXISTS", None
        return "ODD", msg


def stats(ys):
    if not ys:
        return None
    return {"mean": sum(ys) / len(ys), "min": min(ys), "max": max(ys),
            "pk2pk": max(ys) - min(ys), "n": len(ys)}


def read_graph(mc, graph, maxpts=128):
    xs, ys = [], []
    for i in range(maxpts):
        try:
            x, y = mc.get_magnetic_graph_point(graph, i)
        except Exception:
            break
        xs.append(x)
        ys.append(y)
    return xs, ys


def main(argv):
    quit_after = "--quit" in argv
    max_id = 400
    if "--max-id" in argv:
        max_id = int(argv[argv.index("--max-id") + 1])
    os.makedirs(OUT_DIR, exist_ok=True)
    ts = time.strftime("%m%d_%H%M%S")

    from ansys.motorcad.core import MotorCAD
    print("启动 Motor-CAD (前台) ...")
    mc = MotorCAD()
    results = {"when": ts, "probe_round": 4}
    try:
        mc.load_from_file(MOT_SRC)

        # ---- ID 枚举 (无求解) ----
        exist_ids, odd = [], {}
        for gid in range(max_id + 1):
            kind, payload = classify(mc, gid)
            if kind in ("EXISTS", "OK"):
                exist_ids.append(gid)
            elif kind == "ODD":
                odd[gid] = payload
        print("存在的图 ID (%d 个): %s" % (len(exist_ids), exist_ids))
        if odd:
            print("异样报错: %s" % json.dumps(odd, ensure_ascii=False))
        results["exist_ids"] = exist_ids
        results["odd"] = odd

        # ---- 图名 RPC 试探 ----
        rpc_found = {}
        probe_id = exist_ids[0] if exist_ids else 0
        for meth in NAME_RPCS:
            try:
                r = mc.connection.send_and_receive(meth, [probe_id])
                rpc_found[meth] = r
                print("  [RPC 可用] %s(%s) = %s" % (meth, probe_id, r))
            except Exception as e:
                print("  [RPC 不可用] %s: %s" % (meth, str(e)[:80]))
        results["name_rpcs"] = rpc_found

        id_names = {}
        name_rpc = next(iter(rpc_found), None)
        if name_rpc and rpc_found[name_rpc] not in (None, ""):
            for gid in exist_ids:
                try:
                    id_names[gid] = mc.connection.send_and_receive(
                        name_rpc, [gid])
                except Exception:
                    id_names[gid] = None
            results["id_names"] = id_names
            print("ID->图名: %s" % json.dumps(id_names, ensure_ascii=False))

        # ---- 求解一次, 读全部存在图的波形 ----
        for var in ["ElectromagneticForcesCalc_Load",
                    "ElectromagneticForcesCalc_OC"]:
            mc.set_variable(var, True)
        print("求解 (负载点, OC/Load 力已开) ...")
        t0 = time.time()
        mc.do_magnetic_calculation()
        print("  耗时 %.1f s" % (time.time() - t0))

        waves = {}
        for gid in exist_ids:
            xs, ys = read_graph(mc, gid)
            if ys:
                waves[str(gid)] = {"name": id_names.get(gid),
                                   "stats": stats(ys),
                                   "x0": xs[0], "x_end": xs[-1],
                                   "x": xs, "y": ys}
        results["waveforms"] = waves
        print("有数据的图 %d 个:" % len(waves))
        for gid, w in waves.items():
            print("  id=%s name=%s x:[%.3g..%.3g] %s"
                  % (gid, w["name"], w["x0"], w["x_end"], w["stats"]))

        res_path = os.path.join(OUT_DIR, "probe3_results_%s.json" % ts)
        with open(res_path, "w", encoding="utf-8") as f:
            json.dump(results, f, ensure_ascii=False, indent=2)
        print("RESULTS: %s" % res_path)
        return 0
    finally:
        if quit_after:
            try:
                mc.quit()
            except Exception:
                pass
        else:
            print("[提示] Motor-CAD 保持前台打开供检查。")


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
