#!/usr/bin/env bash
# ============================================================================
#  모션그래픽 통합 제작환경 — 원샷 설치 스크립트 (macOS)
#  044 프로젝트에서 실제로 설치·렌더 검증된 구성을 처음부터 재현한다.
#
#  사용법:
#    curl -fsSL https://design-portfolio-7yo.pages.dev/motion-stack-setup.sh -o setup.sh
#    bash setup.sh            # 전체 설치
#    bash setup.sh --check    # 설치 상태만 확인(아무것도 설치하지 않음)
#
#  ★ GitHub에 접근할 수 없는 환경도 지원한다.
#    시작할 때 GitHub 도달 여부를 검사하고, 막혀 있으면 GitHub을 타는 단계를
#    건너뛴 뒤 오프라인 팩(motion-stack-offline.zip)으로 받도록 안내한다.
#
#  검증 환경: macOS(Darwin 24.6) · Node v24.14.1 · npm 11.11.0 — 2026-10-17
# ============================================================================
set -u

CHECK_ONLY=0
[ "${1:-}" = "--check" ] && CHECK_ONLY=1

SITE="https://design-portfolio-7yo.pages.dev"
ok()   { printf "  \033[32m✔\033[0m %s\n" "$1"; }
warn() { printf "  \033[33m!\033[0m %s\n" "$1"; }
bad()  { printf "  \033[31m✘\033[0m %s\n" "$1"; }
step() { printf "\n\033[1m[%s] %s\033[0m\n" "$1" "$2"; }
run()  { if [ "$CHECK_ONLY" = "1" ]; then warn "건너뜀(--check): $*"; return 0; fi; echo "  $ $*"; "$@"; }

# ─── 0. 사전 요건 ───────────────────────────────────────────────────────────
step 0 "사전 요건 · 네트워크 도달성"

[ "$(uname -s)" = "Darwin" ] || bad "이 스크립트는 macOS 기준이다. Linux는 brew 부분을 apt/dnf로 바꿀 것."

# GitHub 도달성 검사 — 이후 분기의 기준이 된다
GH_OK=0
if curl -fsS --max-time 6 -o /dev/null https://github.com 2>/dev/null; then
  GH_OK=1; ok "GitHub 접근 가능"
else
  warn "GitHub 접근 불가 — GitHub을 타는 단계는 건너뛰고 오프라인 팩 경로를 안내한다"
fi
curl -fsS --max-time 6 -o /dev/null https://registry.npmjs.org && ok "npm 레지스트리 접근 가능" || bad "npm 레지스트리 접근 불가 — Remotion·HyperFrames 설치 불가"
curl -fsS --max-time 6 -o /dev/null https://pypi.org && ok "PyPI 접근 가능" || bad "PyPI 접근 불가 — Manim·Blender MCP 설치 불가"

if command -v brew >/dev/null 2>&1; then
  ok "Homebrew $(brew --version | head -1 | awk '{print $2}')"
  [ "$GH_OK" = "0" ] && warn "Homebrew는 바이너리(bottle)를 ghcr.io(GitHub 인프라)에서 받는다. 차단 시 7번의 대안을 쓸 것."
else
  bad "Homebrew 없음 — brew.sh 안내대로 설치하거나, 7번의 비-Homebrew 대안을 쓸 것"
fi

if command -v node >/dev/null 2>&1; then
  NODE_MAJOR=$(node -v | sed 's/v\([0-9]*\).*/\1/')
  if [ "$NODE_MAJOR" -ge 20 ]; then ok "Node $(node -v) / npm $(npm -v)"
  else bad "Node $(node -v) — Remotion은 ^20.19 || ^22.13 || >=24 필요"; fi
else
  warn "Node 없음 → 설치 (또는 nodejs.org 공식 설치본 사용)"
  run brew install node
fi

command -v claude >/dev/null 2>&1 && ok "Claude Code CLI 있음" || bad "Claude Code CLI 없음 — 설치 후 다시 실행할 것"

# ─── 1. 공통 시스템 패키지 ──────────────────────────────────────────────────
step 1 "시스템 패키지 (ffmpeg · uv · Manim 렌더 의존성)"
# ffmpeg : Remotion/HyperFrames/algorithmic-art의 영상 인코딩
# uv     : uvx로 Blender MCP 서버 실행
# cairo/pango/pkgconf : Manim 렌더 백엔드 (※ brew 공식 이름은 pkg-config가 아니라 pkgconf)
if command -v brew >/dev/null 2>&1; then
  for pkg in ffmpeg uv cairo pango pkgconf; do
    if brew list --versions "$pkg" >/dev/null 2>&1; then ok "$pkg $(brew list --versions $pkg | awk '{print $2}')"
    else run brew install "$pkg"; fi
  done
else
  warn "Homebrew 없이 진행 — ffmpeg는 ffmpeg.org 공식 빌드, uv는 'pip3 install --user uv'로 대체 가능"
fi

# ─── 2. Remotion (npm — GitHub 불필요) ──────────────────────────────────────
step 2 "Remotion — React로 영상을 만드는 프레임워크"
# 본체는 npm 레지스트리에서 받는다 → GitHub 없이 설치된다.
cat <<'EOS'
  새 프로젝트 (전역 설치 없음, 프로젝트 단위):
    npx create-video@latest my-video
    cd my-video && npm install
    npx remotion studio                            # 미리보기
    npx remotion render HelloMotion out/hello.mp4  # 스타터 팩 예제 렌더

  ⚠️ 기본 스캐폴드의 MyComp는 null을 반환한다 → 빈 영상이 정상.
     동작 확인은 스타터 팩의 HelloMotion으로 할 것.
EOS
if [ "$GH_OK" = "1" ]; then
  echo "  공식 스킬 12종(프로젝트 스코프):  cd my-video && npx remotion skills add"
else
  warn "Remotion 공식 스킬 12종은 GitHub에서 받는다 → 현재 환경에서는 불가."
  warn "라이선스(자체 라이선스)상 오프라인 팩에도 포함하지 않았다. 본체만으로도 제작은 가능하다."
fi

# ─── 3. HyperFrames ────────────────────────────────────────────────────────
step 3 "HyperFrames — HTML+CSS+GSAP로 영상을 만드는 프레임워크 (HeyGen, Apache-2.0)"
if claude plugin list 2>/dev/null | grep -q "hyperframes@hyperframes"; then
  ok "플러그인 설치됨 (스킬 9종 전역 적용)"
elif [ "$GH_OK" = "1" ]; then
  run claude plugin marketplace add heygen-com/hyperframes
  run claude plugin install hyperframes@hyperframes
else
  warn "플러그인 설치는 GitHub 마켓플레이스를 탄다 → 현재 환경에서는 불가."
  echo "    대안 ①  CLI는 npm이라 그대로 쓸 수 있다:  npx --yes hyperframes@0.8.167 render"
  echo "    대안 ②  스킬 9종은 오프라인 팩에 포함돼 있다:"
  echo "            curl -fsSL $SITE/motion-stack-offline.zip -o pack.zip"
  echo "            unzip pack.zip && cd motion-stack-offline && bash install-offline.sh"
fi

# ─── 4. MCP for Blender (PyPI — GitHub 불필요) ──────────────────────────────
step 4 "MCP for Blender — Claude가 Blender를 직접 조작"
if [ -d "/Applications/Blender.app" ]; then
  ok "Blender 설치됨"
elif command -v brew >/dev/null 2>&1; then
  run brew install --cask blender
else
  warn "blender.org에서 직접 받아 설치할 것 (GitHub 불필요)"
fi

if claude mcp list 2>/dev/null | grep -q "^blender"; then
  ok "MCP 서버 blender 등록됨"
else
  run claude mcp add -s user blender -- uvx mcp-for-blender
fi

# 애드온은 PyPI 패키지(blender_mcp/bundled/addon.py)에 번들돼 서버가 직접 설치한다.
# (검증: 설치본과 패키지 번들본의 sha256이 동일 — GitHub에서 받을 필요 없음)
BL_ADDON="$HOME/Library/Application Support/Blender/5.2/scripts/addons/blender_mcp.py"
[ -f "$BL_ADDON" ] && ok "애드온 설치됨 (PyPI 번들 경유)" || warn "애드온 미설치 — Blender 실행 후 MCP 서버가 자동 배치한다"

cat <<'EOS'
  ⚠️ 여기부터는 GUI라 자동화할 수 없다:
     1) Blender 실행
     2) Edit → Preferences → Add-ons → "MCP for Blender" 검색 → 활성화
     3) 3D 뷰포트에서 N → 사이드바 → "Start MCP Server"
EOS

# ─── 5. Manim CE (PyPI — GitHub 불필요 / 스킬만 GitHub) ─────────────────────
step 5 "Manim CE — 수학·개념 애니메이션"
PYBIN="$HOME/Library/Python/3.11/bin"
export PATH="$PYBIN:$PATH"
command -v manim >/dev/null 2>&1 && ok "$(manim --version 2>&1 | head -1)" || run pip3 install --user manim

if [ -d "$HOME/.claude/skills/manim-skill" ]; then
  ok "스킬 manim-skill 설치됨"
elif [ "$GH_OK" = "1" ]; then
  run git clone https://github.com/awesome-skills/manim-skill.git "$HOME/.claude/skills/manim-skill"
else
  warn "스킬은 GitHub 저장소다 → 오프라인 팩에 MIT 라이선스로 포함돼 있다(아래 7번)"
fi

# pip --user 바이너리는 기본 PATH에 없다 — 가장 흔한 실패 원인
for RC in "$HOME/.zshrc" "$HOME/.bash_profile"; do
  if [ -f "$RC" ] && grep -q 'Library/Python/3.11/bin' "$RC"; then ok "PATH 등록됨: $RC"
  elif [ "$CHECK_ONLY" = "0" ]; then
    echo 'export PATH="$HOME/Library/Python/3.11/bin:$PATH"' >> "$RC"; ok "PATH 추가: $RC (새 터미널부터)"
  fi
done
echo "  현재 셸 즉시 적용: export PATH=\"\$HOME/Library/Python/3.11/bin:\$PATH\""

# ─── 6. algorithmic-art ────────────────────────────────────────────────────
step 6 "algorithmic-art — 제너러티브 아트 (캔버스·SVG·셰이더·루프 영상)"
if [ -d "$HOME/.claude/skills/algorithmic-art" ]; then
  ok "스킬 설치됨"
elif [ "$GH_OK" = "1" ]; then
  run git clone https://github.com/Pardesco/algorithmic-art-skill.git "$HOME/.claude/skills/algorithmic-art"
else
  warn "스킬은 GitHub 저장소다 → 오프라인 팩에 MIT 라이선스로 포함돼 있다(아래 7번)"
fi

# ─── 7. GitHub 차단 환경용 오프라인 팩 ──────────────────────────────────────
if [ "$GH_OK" = "0" ]; then
step 7 "오프라인 팩 — GitHub을 타는 자산을 한 번에 받기"
cat <<EOS
  이 팩에는 manim-skill(MIT) · algorithmic-art(MIT) · hyperframes 스킬 9종(Apache-2.0)과
  렌더 검증된 스타터 2종이 들어 있다. 전부 이 사이트(Cloudflare)에서 직접 받는다.

    curl -fsSL $SITE/motion-stack-offline.zip -o motion-stack-offline.zip
    unzip motion-stack-offline.zip
    cd motion-stack-offline && bash install-offline.sh

  Homebrew까지 막힌 경우의 대안:
    ffmpeg  → ffmpeg.org 공식 빌드 또는 conda-forge
    Blender → blender.org 직접 다운로드
    uv      → pip3 install --user uv
    Manim 의존성(cairo·pango) → conda-forge 채널 권장
EOS
fi

# ─── 최종 확인 ─────────────────────────────────────────────────────────────
step "✓" "설치 확인"
printf "  %-16s %s\n" "node"        "$(node -v 2>/dev/null || echo 없음)"
printf "  %-16s %s\n" "ffmpeg"      "$(ffmpeg -version 2>/dev/null | head -1 | awk '{print $3}' || echo 없음)"
printf "  %-16s %s\n" "uv"          "$(uv --version 2>/dev/null | awk '{print $2}' || echo 없음)"
printf "  %-16s %s\n" "manim"       "$(manim --version 2>&1 | head -1 | awk '{print $NF}' || echo 없음)"
printf "  %-16s %s\n" "Blender"     "$([ -d /Applications/Blender.app ] && echo 설치됨 || echo 없음)"
printf "  %-16s %s\n" "MCP blender" "$(claude mcp list 2>/dev/null | grep -c '^blender') 개"
printf "  %-16s %s\n" "스킬 폴더"   "$(ls ~/.claude/skills 2>/dev/null | wc -l | tr -d ' ') 개"

cat <<EOS

──────────────────────────────────────────────────────────────────────
 동작 확인 (스타터 팩)
   curl -fsSL $SITE/motion-stack-starters.zip -o starters.zip
   unzip starters.zip && cd motion-stack-starters/remotion-starter
   npm install && npx remotion render HelloMotion out/hello.mp4

 Claude Code에서 호출하는 법
   "Remotion으로 15초 인트로 만들어줘"       → remotion-* 스킬
   "/hyperframes로 제품 소개 영상 만들어줘"   → hyperframes 라우터 스킬
   "매님으로 푸리에 변환 시각화해줘"           → manim-skill
   "코드로 제너러티브 아트 만들어줘"           → algorithmic-art
   "블렌더로 이 장면 만들어줘"                 → blender MCP (GUI로 서버 시작 후)
──────────────────────────────────────────────────────────────────────
EOS
