#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ObesityResponderSubpheno (오베시티리스폰서서브페노)

비만 약물치료의 subphenotype × drug class × time × maintenance 4D ontology를
기반으로 미탐색 cell을 ranking하고, 한국 코호트 적용성과 한국어 hypothesis card,
STROBE-RCT/SPIRIT protocol skeleton, 한국어 IIT/grant proposal abstract를 생성하는
연구 아이디어 생성 도구이다.

DISCLAIMER: 본 도구는 연구 아이디어 발굴용 mock 데이터 기반 보조 도구이다.
임상 진료, 환자 의사결정, 약물 처방, 보험 청구의 근거로 사용하면 안 된다.
실제 임상 적용 전에는 최신 문헌, 가이드라인, 라벨, 한국 보험기준을 직접 확인해야 한다.
외부 네트워크 호출은 일절 수행하지 않으며, 모든 mock corpus는 구조 시연용이다.
"""

from __future__ import annotations

import argparse
import json
import math
import os
import sys
from typing import Any

DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")

DISCLAIMER_KO = (
    "[디스클레이머] 본 출력은 mock 데이터 기반 연구 아이디어 발굴용 보조 결과이며, "
    "임상 진료/처방/보험청구 근거로 사용할 수 없습니다. 실제 적용 전 최신 가이드라인, "
    "라벨, 보험기준, 원문 RCT를 직접 확인하십시오."
)


def _load_json(name: str) -> Any:
    path = os.path.join(DATA_DIR, name)
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def load_all() -> dict[str, Any]:
    return {
        "subphenotypes": _load_json("subphenotypes.json")["subphenotypes"],
        "drug_classes": _load_json("drug_classes.json")["drug_classes"],
        "time_buckets": _load_json("time_buckets.json")["time_buckets"],
        "maintenance": _load_json("maintenance.json")["maintenance_modes"],
        "corpus": _load_json("corpus.json")["studies"],
        "korean_cohorts": _load_json("korean_cohorts.json")["cohorts"],
        "labels": _load_json("labels.json")["labels"],
        "guidelines": _load_json("guidelines.json")["guidelines"],
    }


# ---------------------------------------------------------------------------
# 4D cell construction & scoring
# ---------------------------------------------------------------------------


def build_cells(data: dict[str, Any]) -> list[dict[str, Any]]:
    """Construct the 4D ontology cells.

    cell key = (subpheno, drug_class, time_bucket, maintenance_mode)
    """
    cells: list[dict[str, Any]] = []
    for sp in data["subphenotypes"]:
        for dc in data["drug_classes"]:
            for tb in data["time_buckets"]:
                for mm in data["maintenance"]:
                    cells.append(
                        {
                            "subpheno_id": sp["id"],
                            "subpheno_ko": sp["ko"],
                            "drug_id": dc["id"],
                            "drug_ko": dc["ko"],
                            "time_id": tb["id"],
                            "weeks": tb["weeks"],
                            "maint_id": mm["id"],
                            "maint_ko": mm["ko"],
                        }
                    )
    return cells


def published_count_for_cell(cell: dict[str, Any], corpus: list[dict[str, Any]]) -> int:
    cnt = 0
    for s in corpus:
        if cell["drug_id"] != s.get("drug_class"):
            continue
        if cell["subpheno_id"] not in (s.get("subphenotypes") or []):
            continue
        # time 일치도 ±20% 허용
        sw = s.get("time_weeks") or 0
        if sw == 0:
            continue
        if abs(sw - cell["weeks"]) / cell["weeks"] > 0.25:
            continue
        # maintenance
        s_mode = s.get("maintenance_mode")
        if cell["maint_id"] == "persistence":
            # 지속 복용은 long-term + non-discontinuation 가정
            if s_mode in (None, "persistence"):
                cnt += 1
        elif cell["maint_id"] == "rebound":
            if s_mode in ("rebound", None) and cell["weeks"] >= 52:
                # rebound는 명시 거의 없음
                cnt += 1 if s_mode == "rebound" else 0
        elif cell["maint_id"] == "post_discontinuation":
            if s_mode == "post_discontinuation":
                cnt += 1
        elif cell["maint_id"] == "dose_taper":
            if s_mode == "dose_taper":
                cnt += 1
    return cnt


def expected_count(cell: dict[str, Any]) -> float:
    """Heuristic expected publication count for a cell.

    Higher for default_essential + GLP-1RA + 52/68wk + persistence.
    """
    base = 1.0
    if cell["subpheno_id"] == "default_essential":
        base *= 6.0
    elif cell["subpheno_id"] in ("adipose_visceral", "hepatic_predominant_mash"):
        base *= 2.0
    elif cell["subpheno_id"] in ("monogenic_lepr_mc4r_pomc", "bbs_syndromic"):
        base *= 0.5
    if cell["drug_id"] in ("glp1_ra", "glp1_gip_dual"):
        base *= 3.0
    elif cell["drug_id"] in ("triple_agonist", "cagrisema", "oral_glp1"):
        base *= 1.2
    elif cell["drug_id"] == "setmelanotide":
        base *= 0.5
    if cell["weeks"] in (52, 68, 72):
        base *= 2.0
    elif cell["weeks"] in (24, 104):
        base *= 1.0
    else:
        base *= 0.5
    if cell["maint_id"] == "persistence":
        base *= 2.0
    elif cell["maint_id"] == "post_discontinuation":
        base *= 0.6
    elif cell["maint_id"] == "rebound":
        base *= 0.3
    elif cell["maint_id"] == "dose_taper":
        base *= 0.2
    return base


def korean_feasibility(
    cell: dict[str, Any],
    cohorts: list[dict[str, Any]],
    drug_classes: list[dict[str, Any]],
    labels: list[dict[str, Any]],
) -> float:
    score = 0.0
    # cohort applicability
    for c in cohorts:
        if cell["subpheno_id"] in c["applicable_subphenotypes"]:
            score = max(score, c["feasibility_score"])
    # drug availability in KR
    drug = next((d for d in drug_classes if d["id"] == cell["drug_id"]), None)
    if drug:
        status = drug.get("korean_status", "")
        if "MFDS 승인" in status or "급여" in status:
            score *= 1.0
        elif "임상" in status:
            score *= 0.6
        elif "미승인" in status:
            score *= 0.3
    return round(min(score, 1.0), 3)


def clinical_impact(cell: dict[str, Any]) -> float:
    impact = 0.5
    if cell["subpheno_id"] in ("hepatic_predominant_mash", "post_bariatric_regain"):
        impact = 0.9
    elif cell["subpheno_id"] in ("sarcopenic_obesity", "adolescent_obesity", "adipose_visceral"):
        impact = 0.85
    elif cell["subpheno_id"] in ("monogenic_lepr_mc4r_pomc", "bbs_syndromic", "hypothalamic_obesity"):
        impact = 0.95
    elif cell["subpheno_id"] in ("pcos_hyperandrogenic", "cah_obesity"):
        impact = 0.8
    elif cell["subpheno_id"] == "pregnancy_postpartum":
        impact = 0.7
    elif cell["subpheno_id"] == "default_essential":
        impact = 0.55
    if cell["maint_id"] in ("rebound", "post_discontinuation", "dose_taper"):
        impact += 0.1
    return min(impact, 1.0)


def iit_acceptance(cell: dict[str, Any], drug_classes: list[dict[str, Any]]) -> float:
    drug = next((d for d in drug_classes if d["id"] == cell["drug_id"]), None)
    if not drug:
        return 0.3
    status = drug.get("korean_status", "")
    base = 0.5
    if "MFDS 승인" in status:
        base = 0.75
    if "임상" in status:
        base = 0.55
    if cell["maint_id"] in ("post_discontinuation", "rebound", "dose_taper"):
        base += 0.15
    if cell["weeks"] in (24, 52):
        base += 0.05
    return round(min(base, 1.0), 3)


def score_cell(
    cell: dict[str, Any],
    corpus: list[dict[str, Any]],
    cohorts: list[dict[str, Any]],
    drug_classes: list[dict[str, Any]],
    labels: list[dict[str, Any]],
) -> dict[str, Any]:
    pub = published_count_for_cell(cell, corpus)
    exp = expected_count(cell)
    novelty = max(0.0, 1.0 - (pub / max(exp, 0.1)))
    novelty = min(novelty, 1.0)
    impact = clinical_impact(cell)
    feas = korean_feasibility(cell, cohorts, drug_classes, labels)
    iit = iit_acceptance(cell, drug_classes)
    priority = round(novelty * impact * (0.4 + 0.6 * feas) * (0.5 + 0.5 * iit), 4)
    out = dict(cell)
    out.update(
        {
            "published_n": pub,
            "expected_n": round(exp, 2),
            "novelty": round(novelty, 3),
            "clinical_impact": round(impact, 3),
            "korean_feasibility": feas,
            "iit_acceptance": iit,
            "priority": priority,
        }
    )
    return out


def rank_cells(data: dict[str, Any]) -> list[dict[str, Any]]:
    cells = build_cells(data)
    scored = [
        score_cell(c, data["corpus"], data["korean_cohorts"], data["drug_classes"], data["labels"])
        for c in cells
    ]
    # 미탐색에 한정: published_n == 0 우선 + priority 정렬
    scored.sort(key=lambda x: (x["published_n"] > 0, -x["priority"]))
    return scored


# ---------------------------------------------------------------------------
# Output generators
# ---------------------------------------------------------------------------


def cmd_top(data: dict[str, Any], n: int) -> None:
    ranked = rank_cells(data)
    unexplored = [c for c in ranked if c["published_n"] == 0]
    print("=" * 78)
    print("[ObesityResponderSubpheno] 미탐색 4D cell Top {0}".format(n))
    print("총 cell 수:", len(ranked), "| 미탐색 cell 수:", len(unexplored))
    print("=" * 78)
    for i, c in enumerate(unexplored[:n], 1):
        print(
            "\n[{i}] priority={p:.4f} novelty={nv} impact={imp} KR_feasibility={f} IIT={iit}".format(
                i=i,
                p=c["priority"],
                nv=c["novelty"],
                imp=c["clinical_impact"],
                f=c["korean_feasibility"],
                iit=c["iit_acceptance"],
            )
        )
        print("  Subphenotype : {0}".format(c["subpheno_ko"]))
        print("  Drug class   : {0}".format(c["drug_ko"]))
        print("  Time         : {0}주".format(c["weeks"]))
        print("  Maintenance  : {0}".format(c["maint_ko"]))
        print("  Published n  : {0} (expected ~{1})".format(c["published_n"], c["expected_n"]))
    print("\n" + DISCLAIMER_KO)


def cmd_subpheno(data: dict[str, Any], subpheno_id: str) -> None:
    sp = next((s for s in data["subphenotypes"] if s["id"] == subpheno_id or s["ko"] == subpheno_id), None)
    if not sp:
        print("[ERROR] subphenotype을 찾을 수 없음: {0}".format(subpheno_id))
        print("사용 가능한 ID 목록:")
        for s in data["subphenotypes"]:
            print("  - {0} ({1})".format(s["id"], s["ko"]))
        return
    ranked = rank_cells(data)
    sp_cells = [c for c in ranked if c["subpheno_id"] == sp["id"]]
    unexplored = [c for c in sp_cells if c["published_n"] == 0]
    print("=" * 78)
    print("[Subphenotype Gap] {0}".format(sp["ko"]))
    print("정의:", sp["criteria"])
    print("KR cutoff:", sp["bmi_cutoff_kr"])
    print("KR 유병률 추정:", sp["korean_prevalence_estimate"])
    print("총 cell:", len(sp_cells), "| 미탐색:", len(unexplored))
    print("=" * 78)
    for c in unexplored[:10]:
        print(
            "  - {drug} | {wk}주 | {maint} | priority={p:.3f}".format(
                drug=c["drug_ko"], wk=c["weeks"], maint=c["maint_ko"], p=c["priority"]
            )
        )
    print("\n" + DISCLAIMER_KO)


def cmd_drug(data: dict[str, Any], drug_id: str) -> None:
    dc = next((d for d in data["drug_classes"] if d["id"] == drug_id or d["ko"] == drug_id), None)
    if not dc:
        print("[ERROR] drug class를 찾을 수 없음: {0}".format(drug_id))
        print("사용 가능한 ID 목록:")
        for d in data["drug_classes"]:
            print("  - {0} ({1})".format(d["id"], d["ko"]))
        return
    ranked = rank_cells(data)
    dc_cells = [c for c in ranked if c["drug_id"] == dc["id"]]
    unexplored = [c for c in dc_cells if c["published_n"] == 0]
    print("=" * 78)
    print("[Drug class Gap] {0}".format(dc["ko"]))
    print("예시:", ", ".join(dc.get("examples", [])))
    print("KR status:", dc.get("korean_status", ""))
    print("기대 체중감소:", dc.get("typical_weight_loss_pct", ""))
    print("Rebound risk:", dc.get("rebound_risk", ""))
    print("총 cell:", len(dc_cells), "| 미탐색:", len(unexplored))
    print("=" * 78)
    for c in unexplored[:10]:
        print(
            "  - {sp} | {wk}주 | {maint} | priority={p:.3f}".format(
                sp=c["subpheno_ko"], wk=c["weeks"], maint=c["maint_ko"], p=c["priority"]
            )
        )
    print("\n" + DISCLAIMER_KO)


def _select_top_cell(data: dict[str, Any]) -> dict[str, Any] | None:
    ranked = rank_cells(data)
    unexplored = [c for c in ranked if c["published_n"] == 0]
    return unexplored[0] if unexplored else None


def cmd_card(data: dict[str, Any]) -> None:
    cell = _select_top_cell(data)
    if cell is None:
        print("[INFO] 미탐색 cell이 없습니다.")
        return
    sp = next(s for s in data["subphenotypes"] if s["id"] == cell["subpheno_id"])
    dc = next(d for d in data["drug_classes"] if d["id"] == cell["drug_id"])
    cohort_match = [
        c["ko"]
        for c in data["korean_cohorts"]
        if cell["subpheno_id"] in c["applicable_subphenotypes"]
    ]
    print("=" * 78)
    print("[한국어 가설 카드 / Korean Hypothesis Card]")
    print("=" * 78)
    print("제목: {0} 환자에서 {1}의 {2}주 시점 {3} 평가".format(
        sp["ko"], dc["ko"], cell["weeks"], cell["maint_ko"]
    ))
    print()
    print("배경:")
    print("  - {0}는 한국에서 추정 유병률 {1} 수준이며, BMI cutoff {2}.".format(
        sp["ko"], sp["korean_prevalence_estimate"], sp["bmi_cutoff_kr"]
    ))
    print("  - {0} 계열은 일반 비만에서 평균 {1} 체중감소를 보이나, 본 subphenotype에 대한 데이터는 부족.".format(
        dc["ko"], dc.get("typical_weight_loss_pct", "데이터 부족")
    ))
    print()
    print("가설(H1):")
    print("  {0} 환자에 {1}을(를) {2}주간 사용하면 표준치료 대비 우월한 체중감소 및 {3} 결과를 보일 것이다.".format(
        sp["ko"], dc["ko"], cell["weeks"], cell["maint_ko"]
    ))
    print()
    print("Primary endpoint: {0}주 시점 baseline 대비 체중변화율 (%)".format(cell["weeks"]))
    print("Secondary endpoint: {0}, 허리둘레, 내장지방, HbA1c, ALT/AST, MASLD 점수, PROs".format(cell["maint_ko"]))
    print()
    print("적용 가능 한국 코호트: {0}".format(", ".join(cohort_match) if cohort_match else "신규 prospective IIT 필요"))
    print()
    print("Novelty/Priority:")
    print("  novelty={n}  clinical_impact={imp}  KR_feasibility={f}  priority={p:.4f}".format(
        n=cell["novelty"], imp=cell["clinical_impact"], f=cell["korean_feasibility"], p=cell["priority"]
    ))
    print("\n" + DISCLAIMER_KO)


def cmd_protocol(data: dict[str, Any]) -> None:
    cell = _select_top_cell(data)
    if cell is None:
        print("[INFO] 미탐색 cell이 없습니다.")
        return
    sp = next(s for s in data["subphenotypes"] if s["id"] == cell["subpheno_id"])
    dc = next(d for d in data["drug_classes"] if d["id"] == cell["drug_id"])

    print("=" * 78)
    print("[Protocol Skeleton / STROBE-RCT · SPIRIT 호환 한국어 초안]")
    print("=" * 78)
    print()
    print("1. Title: {0} 환자에서 {1}의 {2}주 무작위배정 효능·안전성 시험".format(
        sp["ko"], dc["ko"], cell["weeks"]
    ))
    print()
    print("2. Background & Rationale (SPIRIT 6a):")
    print("   - {0}는 일반 비만과 다른 병태생리를 갖는다. 본 시험은 표준치료 대비 {1} 효과를 검증한다.".format(
        sp["ko"], dc["ko"]
    ))
    print()
    print("3. Objectives (SPIRIT 7):")
    print("   - 1차: {0}주 시점 체중변화율 (%)".format(cell["weeks"]))
    print("   - 2차: {0} 평가, 허리둘레, 내장지방 CT, MASLD score, HbA1c".format(cell["maint_ko"]))
    print()
    print("4. Trial Design (SPIRIT 8): 1:1 무작위 배정, 이중맹검, 활성대조 또는 표준치료")
    print()
    print("5. Eligibility (SPIRIT 10):")
    print("   - 포함: {0} 진단기준 충족 ({1}), BMI {2}".format(
        sp["ko"], sp["criteria"], sp["bmi_cutoff_kr"]
    ))
    print("   - 제외: 임신/수유, 활동성 악성종양, 위장관 수술 6개월 이내, 췌장염 병력")
    print()
    print("6. Interventions (SPIRIT 11):")
    print("   - 시험군: {0} (titration 일정 별표). 유지/감량 모드: {1}".format(
        dc["ko"], cell["maint_ko"]
    ))
    print("   - 대조군: 위약 또는 표준치료 (KSSO 2023 권고)")
    print()
    print("7. Outcomes (SPIRIT 12):")
    print("   - Primary: 체중변화율 % (mITT)")
    print("   - Secondary: ≥5%/10%/15% 도달 비율, 허리둘레, 내장지방, MASLD/MASH 지표")
    print("   - Safety: GI AE, hypoglycemia, gallbladder, pancreatitis, thyroid")
    print()
    print("8. Sample Size (SPIRIT 14): two-sample t-test, α=0.025, power=0.9")
    print("   추정 효과크기 d=0.4, dropout 20% 가정 시 N≈260 (군당 130)")
    print()
    print("9. Randomization & Blinding (SPIRIT 16-17): permuted-block, central randomization")
    print()
    print("10. Statistical Analysis (SPIRIT 20): mITT 분석, multiple imputation,")
    print("    KM curve digitization 시 Hoyle-Henley 방법 사용")
    print()
    print("11. Korean Cohort Integration: KORACO/BBStopCoach RWE/NHIS/KoGES external validation")
    print()
    print("12. Ethics & Dissemination (SPIRIT 24-31): KSSO/KDA 다기관 IRB, ClinicalTrials.gov + CRIS 등록")
    print()
    print(DISCLAIMER_KO)


def cmd_proposal(data: dict[str, Any]) -> None:
    cell = _select_top_cell(data)
    if cell is None:
        print("[INFO] 미탐색 cell이 없습니다.")
        return
    sp = next(s for s in data["subphenotypes"] if s["id"] == cell["subpheno_id"])
    dc = next(d for d in data["drug_classes"] if d["id"] == cell["drug_id"])
    print("=" * 78)
    print("[Grant/IIT Proposal Abstract (한국어, KHIDI/NRF/NIH/Novo/Lilly/BI/Amgen/Pfizer 호환)]")
    print("=" * 78)
    print()
    print("연구과제명: {0} 환자에서 {1}의 {2}주 무작위배정 효능 및 {3} 평가 - 한국 다기관 IIT".format(
        sp["ko"], dc["ko"], cell["weeks"], cell["maint_ko"]
    ))
    print()
    print("배경 및 필요성:")
    print("  현재까지 {0} 계열의 비만 RCT는 본태성 비만 중심으로 수행되어, {1}와 같은 ".format(dc["ko"], sp["ko"]))
    print("  특수 subphenotype에서의 효능·안전성·{0} 자료가 매우 제한적이다. ".format(cell["maint_ko"]))
    print("  한국은 BMI 23 cutoff와 visceral 우세 비만이 흔하여 별도 근거가 필요하다.")
    print()
    print("연구목표:")
    print("  1차: {0} 환자에서 {1} 사용 시 {2}주 체중변화율 우월성 확인".format(
        sp["ko"], dc["ko"], cell["weeks"]
    ))
    print("  2차: {0}, MASLD/허리/내장지방, 한국 보험·라벨 적용성 분석".format(cell["maint_ko"]))
    print()
    print("연구방법: 다기관 RCT (KSSO/KORACO 협력), {0}주 추적, n≈260, KORACO RWE 외부타당화 결합".format(cell["weeks"]))
    print()
    print("기대성과:")
    print("  - {0}의 {1}/IIT 라벨 확장 근거 제공".format(dc["ko"], sp["ko"]))
    print("  - 한국형 비만 phenotype-specific 가이드라인 reference 자료")
    print("  - KHIDI/NRF/NIH 후속과제 연계, 다국가 비교 cohort 확장")
    print()
    print("예산 규모(개략): 다기관 IIT 기준 3년간 약 12-18억원 (KR multicenter)")
    print()
    print("협력기관 후보: KSSO, KSPED, KSGH, KORACO consortium, BBStopCoach RWE")
    print()
    print(DISCLAIMER_KO)


# ---------------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------------


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(
        prog="ObesityResponderSubpheno",
        description=(
            "비만 약물 4D ontology(subphenotype × drug × time × maintenance) 기반 "
            "미탐색 cell ranking, 한국 코호트 적합성, 한국어 가설 카드/Protocol/Proposal 생성기. "
            "연구 아이디어 발굴 보조 도구이며 임상 근거가 아님."
        ),
    )
    p.add_argument("--top", type=int, default=0, help="top N 미탐색 4D cell 출력")
    p.add_argument("--subpheno", type=str, default=None, help="특정 subphenotype id 또는 한국어명")
    p.add_argument("--drug", type=str, default=None, help="특정 drug class id 또는 한국어명")
    p.add_argument("--card", action="store_true", help="한국어 hypothesis card 출력")
    p.add_argument("--protocol", action="store_true", help="STROBE-RCT/SPIRIT protocol skeleton 출력")
    p.add_argument("--proposal", action="store_true", help="한국어 IIT/grant proposal abstract 출력")
    p.add_argument("--list-subpheno", action="store_true", help="subphenotype 목록 출력")
    p.add_argument("--list-drugs", action="store_true", help="drug class 목록 출력")
    p.add_argument("--summary", action="store_true", help="ontology 요약 통계 출력")
    return p


def cmd_list_subpheno(data: dict[str, Any]) -> None:
    print("Subphenotypes ({0}):".format(len(data["subphenotypes"])))
    for s in data["subphenotypes"]:
        print("  - {0:<35s}  {1}".format(s["id"], s["ko"]))


def cmd_list_drugs(data: dict[str, Any]) -> None:
    print("Drug classes ({0}):".format(len(data["drug_classes"])))
    for d in data["drug_classes"]:
        print("  - {0:<25s}  {1}".format(d["id"], d["ko"]))


def cmd_summary(data: dict[str, Any]) -> None:
    n_sp = len(data["subphenotypes"])
    n_dc = len(data["drug_classes"])
    n_tb = len(data["time_buckets"])
    n_mm = len(data["maintenance"])
    total = n_sp * n_dc * n_tb * n_mm
    ranked = rank_cells(data)
    unexplored = sum(1 for c in ranked if c["published_n"] == 0)
    print("=" * 78)
    print("[ObesityResponderSubpheno] 4D Ontology Summary")
    print("=" * 78)
    print("Subphenotypes : {0}".format(n_sp))
    print("Drug classes  : {0}".format(n_dc))
    print("Time buckets  : {0}".format(n_tb))
    print("Maintenance   : {0}".format(n_mm))
    print("Total cells   : {0}".format(total))
    print("Mock corpus n : {0}".format(len(data["corpus"])))
    print("미탐색 cells  : {0} ({1:.1f}%)".format(unexplored, 100 * unexplored / total))
    print("KR cohorts    : {0}".format(len(data["korean_cohorts"])))
    print("Guidelines    : {0}".format(len(data["guidelines"])))
    print("\n" + DISCLAIMER_KO)


def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)
    data = load_all()

    did_anything = False

    if args.list_subpheno:
        cmd_list_subpheno(data)
        did_anything = True
    if args.list_drugs:
        cmd_list_drugs(data)
        did_anything = True
    if args.summary:
        cmd_summary(data)
        did_anything = True
    if args.top and args.top > 0:
        cmd_top(data, args.top)
        did_anything = True
    if args.subpheno:
        cmd_subpheno(data, args.subpheno)
        did_anything = True
    if args.drug:
        cmd_drug(data, args.drug)
        did_anything = True
    if args.card:
        cmd_card(data)
        did_anything = True
    if args.protocol:
        cmd_protocol(data)
        did_anything = True
    if args.proposal:
        cmd_proposal(data)
        did_anything = True

    if not did_anything:
        cmd_summary(data)
        print("\n[Hint] 사용 가능한 옵션:")
        print("  --top 5            상위 5개 미탐색 cell")
        print("  --subpheno ID      특정 subphenotype 갭")
        print("  --drug ID          특정 drug class 갭")
        print("  --card             한국어 hypothesis card")
        print("  --protocol         STROBE-RCT/SPIRIT protocol skeleton")
        print("  --proposal         한국어 IIT/grant proposal")
        print("  --list-subpheno    subphenotype 목록")
        print("  --list-drugs       drug class 목록")

    return 0


if __name__ == "__main__":
    sys.exit(main())
