// 이 파일이 하는 일: "네트워크 명령어 실전" 코스 — 터미널에서 바로 써먹는
// 네트워크 진단 명령 6개(ping·tracert·nslookup·ipconfig·netstat·curl)를
// 실제 출력 예시와 함께 익히고, 마지막에 "인터넷 안 될 때" 진단 순서도로 묶는 정적 학습 페이지.
// 학습 포인트: API 호출이 없는 '내용 고정' 페이지다. 스타일은 global.css의
// 가이드 전용 클래스(step-card, code-block, tip 등)를 재사용한다 — 색을 여기서 하드코딩하지 않는다.
// 명령어 출력 예시는 JSX 중괄호/백틱 충돌을 피하려고 파일 상단의 백틱 문자열 상수로 정의한다.

import { Link } from 'react-router-dom';

// ── 명령어 출력 예시 · 표 상수들 ──

const CODE_PING = `# "그 서버, 살아 있니?" 하고 노크해 보는 명령:
ping edu.awesomedevapp.com

Ping edu.awesomedevapp.com [x.x.x.x] 32바이트 데이터 사용:
x.x.x.x의 응답: 바이트=32 시간=8ms TTL=54
x.x.x.x의 응답: 바이트=32 시간=9ms TTL=54
x.x.x.x의 응답: 바이트=32 시간=8ms TTL=54
x.x.x.x의 응답: 바이트=32 시간=10ms TTL=54

Ping 통계: 보냄 = 4, 받음 = 4, 손실 = 0 (0% 손실)
왕복 시간: 최소 = 8ms, 최대 = 10ms, 평균 = 8ms

읽는 법 세 줄 요약:
· 시간=8ms   → 노크하고 대답 듣기까지 왕복 8밀리초 (낮을수록 빠름)
· 손실 = 0%  → 보낸 노크 4번에 4번 다 대답함 (손실이 있으면 회선 불안정)
· "요청 시간이 만료되었습니다" → 대답 없음. 죽었거나, 길이 끊겼거나,
  일부러 대답 안 하는 서버일 수도 있어요(보안상 ping 무시하는 곳도 많음!)`;

const CODE_PING_COMPARE = `# 가까운 서버 vs 먼 서버 — 응답 속도 비교해 보기
ping naver.com        →  평균 5~15ms   (한국 안, 옆 동네 수준)
ping google.com       →  평균 30~40ms  (아시아 어딘가의 구글 서버)
ping bbc.co.uk        →  평균 250ms+   (영국까지 왕복!)

빛도 지구 반 바퀴를 도는 데 시간이 걸려요.
ms 숫자는 사실상 "물리적 거리 + 환승 횟수"의 합산입니다.`;

const CODE_TRACERT = `# 목적지까지 어떤 환승역(라우터)들을 거치는지 추적:
tracert bbc.co.uk

  1    <1ms   192.168.0.1     ← 1번 홉: 내 공유기 (항상 첫 출발지!)
  2     3ms   10.x.x.x        ← 통신사 동네 장비
  3     5ms   ...             ← 통신사 백본 진입
  ...
  8    35ms   ...             ← 국제 관문 (여기서 해저 케이블로!)
  9   120ms   ...             ← 바다 건너 첫 홉 — 시간이 확 뜁니다
 ...
 14   250ms   x.x.x.x         ← 영국의 BBC 서버 도착

읽는 법:
· 한 줄 = 홉(hop) 하나 = 환승역 하나
· 시간이 갑자기 확 뛰는 구간 = 대륙을 건너는 순간일 확률이 높아요
· 중간에 "* * *" = 그 라우터가 대답을 생략한 것. 뒤가 이어지면 정상
· 끝까지 "* * *"만 나오고 도착을 못 하면 → 그 지점 이후 길이 막힌 것`;

const CODE_NSLOOKUP = `# DNS(인터넷 전화번호부)에 직접 질문 던지기:
nslookup edu.awesomedevapp.com

서버:    ...            ← 내 질문을 받아 준 DNS 서버
Address: ...

권한 없는 응답:          ← "원본이 아니라 캐시로 답해줌"이라는 뜻 (정상!)
이름:    edu.awesomedevapp.com
Address: x.x.x.x        ← 우리 학습 플랫폼 서버(AWS EC2 서울)의 실제 IP

# 비교 실험: nslookup naver.com
# 큰 서비스는 Address가 여러 줄 나와요 — 손님(트래픽)을
# 여러 창구로 나눠 받기 위해 IP를 여러 개 등록해 둔 겁니다.`;

const CODE_IPCONFIG = `# 남의 주소 말고 '내' 주소부터 알아야죠:
ipconfig

이더넷 어댑터 이더넷:   (WiFi면 "무선 LAN 어댑터 Wi-Fi")
   IPv4 주소 . . . . : 192.168.0.5    ← 내 사설 IP (아파트 호수)
   서브넷 마스크 . . : 255.255.255.0
   기본 게이트웨이 . : 192.168.0.1    ← 공유기 주소 (아파트 정문)

# 더 자세히 (DNS 서버 주소까지):
ipconfig /all

# 이 명령이 중요한 이유: 뒤에 나올 '진단 순서도'의 출발점이
# 전부 여기서 확인한 두 주소(내 IP, 게이트웨이)이기 때문!`;

const CODE_NETSTAT = `# 내 PC가 지금 누구랑 연결돼 있는지 전부 출력:
netstat -ano

프로토콜  로컬 주소            외부 주소             상태          PID
TCP     192.168.0.5:52310   x.x.x.x:443          ESTABLISHED   4312
TCP     0.0.0.0:5173        0.0.0.0:0            LISTENING     8820
TCP     127.0.0.1:5432      0.0.0.0:0            LISTENING     1204

읽는 법 (한 줄 = 연결 하나):
· 로컬 주소  → 내 쪽 주소:포트
· 외부 주소  → 상대방 주소:포트 (:443이면 HTTPS 접속 중이란 뜻)
· ESTABLISHED → 지금 통화 중인 연결
· LISTENING   → "전화 오면 받을게요" 하고 대기 중인 서버 프로그램
· PID → 그 연결을 쓰는 프로그램 번호 (작업 관리자에서 누군지 찾을 수 있음)

위 예시를 해석하면:
· :443에 접속 중       → 브라우저가 어떤 사이트를 보는 중
· :5173이 LISTENING   → 내가 켜 둔 React(Vite) 개발 서버!
· :5432가 LISTENING   → PostgreSQL이 접속 대기 중 (Docker로 띄웠다면 그것)`;

const CODE_CURL = `# 브라우저 없이 터미널에서 웹 요청 보내기 — 백엔드 개발자의 청진기:
curl https://edu.awesomedevapp.com/api/health

{"status":"UP"}     ← 우리 Spring Boot 서버의 대답! (JSON)

# 자주 쓰는 옵션 3개만 먼저:
curl -i  https://edu.awesomedevapp.com/api/health   # 응답 헤더까지 보기
curl -s  ...                                        # 진행률 표시 숨기기
curl -X POST ...                                    # GET 말고 POST로 보내기

# -i 를 붙이면 이런 게 먼저 나와요:
HTTP/2 200                    ← 상태 코드! 200=성공, 404=없음, 500=서버 폭발
content-type: application/json
server: Caddy                 ← 우리 현관 안내데스크(Caddy)가 응대했다는 서명

브라우저는 사실 curl이 하는 일을 예쁘게 포장한 것뿐이에요.
요청을 '날것'으로 보고 싶을 때, 프론트 없이 백엔드만 테스트하고
싶을 때 curl을 씁니다. 실무에서 정말, 정말 많이 써요.`;

const CODE_FLOWCHART = `"인터넷이 안 돼요!" — 안쪽에서 바깥쪽으로 한 겹씩 벗겨 보는 순서

① 내 PC는 멀쩡한가? (집)
   ipconfig → IPv4 주소가 192.168.x.x 로 잡혀 있나?
   ├─ 주소가 없거나 169.254.x.x → 공유기와 연결 자체가 안 됨.
   │   랜선/WiFi부터 확인!
   └─ 정상이면 ↓

② 공유기까지는 가는가? (아파트 정문)
   ping 192.168.0.1   (①에서 본 '기본 게이트웨이' 주소)
   ├─ 응답 없음 → 공유기 문제. 재부팅의 시간입니다
   └─ 응답 옴 → ↓

③ 바깥세상까지는 가는가? (도로)
   ping 8.8.8.8   (외우기 쉬운 유명 공용 DNS의 IP — 숫자로 직접!)
   ├─ 응답 없음 → 집 밖 회선 문제. 통신사에 연락할 차례
   └─ 응답 옴 → ↓

④ 이름은 찾아지는가? (전화번호부)
   nslookup naver.com
   ├─ 실패 → 회선은 되는데 DNS가 고장!
   │   "인터넷은 되는데 사이트만 안 열림"의 단골 범인
   └─ 성공 → ↓

⑤ 그럼 그 사이트만 문제 (상대방)
   다른 사이트는 열리는데 하나만 안 열리면
   내 잘못이 아니라 그 서버가 아픈 거예요. 기다리세요!

핵심: ③에서 IP(8.8.8.8)는 되는데 ④의 이름 찾기가 실패하면
"회선 O, DNS X"라고 원인을 정확히 쪼갤 수 있어요.
명령어 4개로 통신사 상담원보다 빠른 진단이 끝납니다.`;

const CODE_CHECKLIST = `오늘 배운 6가지 — 한 줄 요약 카드

ping      살아 있니? + 왕복 몇 ms?         (생존 확인·응답 속도)
tracert   거기까지 어떤 길로 가?            (경로의 환승역 추적)
nslookup  그 이름, 번호(IP)로 뭐야?         (DNS에 직접 질문)
ipconfig  그래서 '내' 주소는 뭔데?          (내 IP·게이트웨이 확인)
netstat   내 PC, 지금 누구랑 연결 중?       (연결·대기 포트 목록)
curl      브라우저 없이 서버에 말 걸기       (API 직접 호출·헤더 확인)

전부 설치가 필요 없는, Windows에 이미 들어 있는 도구들이에요.
(curl도 Windows 10 이후 기본 탑재!)`;

// ── 이 페이지 안에서만 쓰는 작은 부품들 ──
// 학습 포인트: 같은 모양이 반복되면 컴포넌트로 뽑는다. props만 바꿔 재사용.
function Section({ n, title, sub, children }) {
  return (
    <section className="step-card" id={`sec-${n}`}>
      <div className="step-head">
        <span className="step-num">{n}</span>
        <div>
          <h3>{title}</h3>
          {sub && <span className="step-sub">{sub}</span>}
        </div>
      </div>
      <div className="step-body">{children}</div>
    </section>
  );
}

function Code({ children }) {
  return <pre className="code-block"><code>{children}</code></pre>;
}

const SECTIONS = [
  { n: 1, label: 'ping' },
  { n: 2, label: 'tracert' },
  { n: 3, label: 'nslookup' },
  { n: 4, label: 'ipconfig' },
  { n: 5, label: 'netstat' },
  { n: 6, label: 'curl' },
  { n: 7, label: '진단 순서도' },
];

export default function NetToolsPage() {
  return (
    <div>
      {/* 히어로: 개념이 아니라 '손'을 훈련하는 코스라는 걸 못박기 */}
      <div className="hero">
        <div className="eyebrow">Course · 네트워크</div>
        <h1>네트워크 명령어 실전<br />— 터미널이 곧 청진기다</h1>
        <p>
          "인터넷이 안 돼요"라는 말 대신 <strong>"게이트웨이까지는 ping이 되는데 DNS 조회가
          실패해요"</strong>라고 말할 수 있게 되는 코스예요. 명령어 6개면 네트워크 문제의
          원인을 의사처럼 진단할 수 있습니다 — 전부 여러분 PC에 이미 설치돼 있어요.
        </p>
        <div className="chip-row">
          <span className="chip">예상 소요 50분</span>
          <span className="chip">명령어 6개 실습</span>
          <span className="chip">준비물: 터미널 하나</span>
        </div>
      </div>

      {/* 섹션 바로가기 */}
      <nav className="pill-nav">
        {SECTIONS.map((s) => (
          <a key={s.n} href={`#sec-${s.n}`}>
            <b>{s.n}</b>
            {s.label}
          </a>
        ))}
      </nav>

      <Section n={1} title="ping — 살아 있니?" sub="노크 한 번으로 생존 확인 + 응답 속도 측정">
        <p>
          <strong>ping</strong>은 상대 서버 방문 앞에서 <strong>노크</strong>하고 대답이
          돌아오기까지 시간을 재는 명령이에요. 가장 단순한데, 그래서 모든 네트워크 진단의
          출발점입니다. 대답이 오면 "살아 있고 길도 뚫려 있다", 안 오면 "죽었거나 길이
          막혔거나 대답을 거부 중" — 셋 중 하나로 좁혀지죠.
        </p>
        <Code>{CODE_PING}</Code>
        <p>
          <span className="icode">시간=8ms</span>의 <strong>ms(밀리초)</strong>는 1000분의 1초.
          내 목소리가 서버까지 갔다가 메아리로 돌아오는 왕복 시간이에요. 게임에서 말하는
          "핑이 튄다"의 그 핑이 바로 이 숫자입니다.
        </p>
        <div className="tip">
          <b>직접 확인해 보기 ①</b> 터미널(<span className="kbd">Win</span>+<span className="kbd">R</span> →
          <span className="icode">cmd</span>)을 열고 <span className="icode">ping edu.awesomedevapp.com</span>을
          쳐 보세요. 우리 학습 플랫폼 서버(EC2 서울)가 대답해요! 이어서 아래처럼 먼 나라
          서버들과 응답 속도를 비교해 보세요.
        </div>
        <Code>{CODE_PING_COMPARE}</Code>
      </Section>

      <Section n={2} title="tracert — 어떤 길로 가?" sub="목적지까지의 환승역을 전부 보여주는 경로 추적">
        <p>
          ping이 "도착했다/못 했다"만 알려 준다면, <strong>tracert</strong>(trace route)는
          <strong> 지나간 정류장을 전부</strong> 보여줘요. 내 데이터는 공유기 → 통신사 →
          백본 → (해외라면) 해저 케이블을 갈아타며 여행하는데, 그 <strong>환승역(홉, hop)</strong>
          하나하나를 시간과 함께 찍어 줍니다.
        </p>
        <svg className="diagram" viewBox="0 0 640 240" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="내 PC에서 공유기, 통신사, 국제 관문을 거쳐 영국 서버까지 가는 홉 경로 도해. tracert는 홉마다 왕복 시간을 찍고, ping은 목적지까지의 전체 왕복만 잰다.">
          <text x="515" y="30" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--amber)">해저 케이블</text>
          <rect x="10" y="44" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
          <text x="60" y="70" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">내 PC</text>
          <text x="60" y="92" textAnchor="middle" fontSize="12" fill="var(--muted)">출발</text>
          <rect x="140" y="44" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="190" y="70" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">공유기</text>
          <text x="190" y="92" textAnchor="middle" fontSize="12" fill="var(--muted)">1번 홉</text>
          <rect x="270" y="44" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="320" y="70" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">통신사 ISP</text>
          <text x="320" y="92" textAnchor="middle" fontSize="12" fill="var(--muted)">2~3번 홉</text>
          <rect x="400" y="44" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="450" y="70" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">국제 관문</text>
          <text x="450" y="92" textAnchor="middle" fontSize="12" fill="var(--muted)">8번 홉</text>
          <rect x="530" y="44" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
          <text x="580" y="70" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">영국 서버</text>
          <text x="580" y="92" textAnchor="middle" fontSize="12" fill="var(--muted)">14번 홉 도착</text>
          <line x1="110" y1="76" x2="133" y2="76" stroke="var(--muted)" strokeWidth="1.5" />
          <polyline points="132,71 140,76 132,81" fill="none" stroke="var(--muted)" strokeWidth="1.5" />
          <line x1="240" y1="76" x2="263" y2="76" stroke="var(--muted)" strokeWidth="1.5" />
          <polyline points="262,71 270,76 262,81" fill="none" stroke="var(--muted)" strokeWidth="1.5" />
          <line x1="370" y1="76" x2="393" y2="76" stroke="var(--muted)" strokeWidth="1.5" />
          <polyline points="392,71 400,76 392,81" fill="none" stroke="var(--muted)" strokeWidth="1.5" />
          <line x1="500" y1="76" x2="523" y2="76" stroke="var(--amber)" strokeWidth="1.5" strokeDasharray="4 3" />
          <polyline points="522,71 530,76 522,81" fill="none" stroke="var(--amber)" strokeWidth="1.5" />
          <text x="6" y="134" fontSize="12" fontWeight="600" fill="var(--teal)">tracert가 찍는 시간</text>
          <text x="190" y="134" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--teal)">{'<1ms'}</text>
          <text x="320" y="134" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--teal)">3~5ms</text>
          <text x="450" y="134" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--teal)">35ms</text>
          <text x="580" y="134" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--teal)">250ms</text>
          <text x="515" y="156" textAnchor="middle" fontSize="12" fill="var(--amber)">바다를 건너며 확 뜀 (120ms~)</text>
          <line x1="30" y1="192" x2="610" y2="192" stroke="var(--primary)" strokeWidth="1.5" />
          <line x1="30" y1="186" x2="30" y2="198" stroke="var(--primary)" strokeWidth="1.5" />
          <line x1="610" y1="186" x2="610" y2="198" stroke="var(--primary)" strokeWidth="1.5" />
          <text x="320" y="220" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--primary)">ping은 이 전체 왕복만 한 번에 잰다 (중간 홉은 안 보임)</text>
        </svg>
        <p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: tracert는 환승역(홉)마다 시간을 찍고, ping은 목적지까지의 왕복만 잰다</p>
        <Code>{CODE_TRACERT}</Code>
        <div className="tip">
          <b>직접 확인해 보기 ②</b> <span className="icode">tracert bbc.co.uk</span> 같은
          <strong> 해외 사이트</strong>로 홉을 세어 보세요. 국내 사이트(10홉 안팎)와 비교하면
          해외는 홉 수도 많고, 어느 순간 시간이 30ms → 120ms로 <strong>점프하는 구간</strong>이
          보여요 — 그게 여러분의 패킷이 바다를 건너는 순간입니다. 1번 홉이 내 공유기
          주소인 것도 꼭 확인!
        </div>
        <div className="warn">
          <b>중간이 * * * 이어도 당황 금지</b> — 보안상 대답을 생략하는 라우터가 많아요.
          마지막 줄에서 목적지에 도착했다면 경로는 정상입니다. 진짜 문제는
          "어느 홉 이후로 <strong>전부</strong> 끊기고 도착도 못 하는" 경우예요.
        </div>
      </Section>

      <Section n={3} title="nslookup — 이름 대신 번호를" sub="DNS 전화번호부에 직접 질문하기">
        <p>
          컴퓨터는 도메인 이름이 아니라 IP 숫자로 서로를 찾아요. 이름을 번호로 바꿔 주는
          전화번호부가 <strong>DNS</strong>고, <strong>nslookup</strong>(name server lookup)은
          그 전화번호부에 <strong>내가 직접 전화를 걸어 물어보는</strong> 명령입니다.
          "브라우저야 비켜 봐, 내가 직접 물어볼게" 하는 거죠.
        </p>
        <Code>{CODE_NSLOOKUP}</Code>
        <p>
          이 명령의 진짜 쓸모는 <strong>문제를 반으로 쪼개는 것</strong>이에요. 사이트가 안
          열릴 때 nslookup이 성공하면 "이름 찾기(DNS)는 정상, 그 뒤가 문제"고, 실패하면
          "범인은 DNS"로 확정 — 뒤에 나올 진단 순서도의 핵심 분기점입니다.
        </p>
      </Section>

      <Section n={4} title="ipconfig — 그래서 나는 누구?" sub="내 IP와 공유기 주소부터 확인하는 습관">
        <p>
          남의 서버를 진단하기 전에 <strong>내 주소부터</strong> 알아야 해요.
          <strong> ipconfig</strong>는 내 PC의 네트워크 명함을 보여주는 명령입니다.
          여기서 봐야 할 건 딱 두 줄 — <strong>내 IPv4 주소</strong>(아파트 호수)와
          <strong> 기본 게이트웨이</strong>(공유기, 즉 아파트 정문)예요.
        </p>
        <Code>{CODE_IPCONFIG}</Code>
        <div className="warn">
          <b>주소가 169.254.x.x 로 보인다면</b> — 공유기(DHCP)한테 주소를 못 받아서
          PC가 임시번호를 스스로 지어낸 상태예요. "저 아직 입주 못 했어요"라는 신호이니
          랜선·WiFi 연결부터 다시 확인해야 합니다.
        </div>
        <div className="tip">
          <b>직접 확인해 보기 ③</b> <span className="icode">ipconfig</span>로 기본 게이트웨이
          주소를 확인한 뒤, 그 주소로 <span className="icode">ping 192.168.0.1</span>(내
          게이트웨이 주소로 바꿔서) 해 보세요. 1ms 안팎으로 즉답이 와요 — 같은 방 안에서의
          대화니까요. 섹션 1에서 잰 해외 서버 250ms와 비교하면 거리감이 확 옵니다.
        </div>
      </Section>

      <Section n={5} title="netstat — 지금 누구랑 통화 중?" sub="내 PC의 모든 연결과 대기 포트 목록">
        <p>
          <strong>netstat</strong>(network statistics)은 내 PC의 <strong>통화 목록</strong>이에요.
          지금 어떤 프로그램이 어디에 접속해 있고(ESTABLISHED), 어떤 프로그램이 전화를
          기다리며 대기 중인지(LISTENING) 전부 보여줍니다.
        </p>
        <Code>{CODE_NETSTAT}</Code>
        <p>
          개발자에게 특히 소중한 순간: <span className="icode">npm run dev</span>를 켰는데
          <strong> "포트가 이미 사용 중입니다"</strong> 에러가 날 때예요.
          <span className="icode">netstat -ano | findstr :5173</span>으로 그 포트를 물고 있는
          PID를 찾고, 작업 관리자에서 누군지 확인하면 범인 검거 끝. Docker로 띄운
          PostgreSQL(5432)이 살아 있는지 확인할 때도 똑같이 씁니다.
        </p>
        <div className="tip">
          <b>직접 확인해 보기 ④</b> 브라우저로 우리 학습 플랫폼을 열어 둔 채
          <span className="icode"> netstat -ano | findstr :443</span>을 실행해 보세요.
          ESTABLISHED 줄들의 <strong>외부 주소</strong> 중에 섹션 3의 nslookup으로 알아낸
          우리 서버 IP가 있나요? 있다면 — 여러분의 브라우저와 서울 EC2 사이의 연결을
          방금 두 눈으로 목격한 겁니다.
        </div>
      </Section>

      <Section n={6} title="curl — 브라우저 없이 API 호출" sub="백엔드 개발자의 필수 도구, 요청을 날것으로 보기">
        <p>
          <strong>curl</strong>은 터미널에서 웹 요청을 보내는 명령이에요. 브라우저가 하는 일의
          <strong> 알맹이만</strong> 남긴 도구죠. 화면도 버튼도 없이, 요청을 보내고 응답을
          글자 그대로 받아 봅니다. 프론트엔드를 거치지 않고 <strong>백엔드만 콕 집어
          테스트</strong>할 수 있어서, Spring Boot API를 만들 때 하루에도 수십 번 쓰게 돼요.
        </p>
        <Code>{CODE_CURL}</Code>
        <p>
          위 예시의 <span className="icode">/api/health</span>처럼 "나 살아 있어요"만 대답하는
          주소를 <strong>헬스체크</strong> 엔드포인트라고 해요. ping이 <strong>서버 기계</strong>의
          생존 확인이라면, curl로 헬스체크를 때리는 건 그 위에서 도는
          <strong> 애플리케이션(Spring Boot)</strong>의 생존 확인 — 기계는 멀쩡한데 앱만 죽는
          경우도 많거든요. 두 진단은 층이 다릅니다.
        </p>
        <div className="tip">
          <b>직접 확인해 보기 ⑤</b> 로컬에서 <span className="icode">npm run dev</span>로 개발
          서버를 켜 두고, 다른 터미널에서 <span className="icode">curl -i http://localhost:5173</span>을
          쳐 보세요. 브라우저가 받던 HTML이 날것 그대로 쏟아져요. 상태 코드
          <span className="icode"> 200</span>도 확인! 이어서 존재하지 않는 주소를 호출해
          <span className="icode"> 404</span>가 어떻게 생겼는지도 구경해 보세요.
        </div>
      </Section>

      <Section n={7} title="진단 순서도 — 인터넷이 안 될 때" sub="집 → 공유기 → DNS → 사이트, 안에서 밖으로 한 겹씩">
        <p>
          이제 배운 명령들을 <strong>수사 순서</strong>로 엮을 차례예요. 원칙은 하나 —
          <strong> 나에게서 가까운 쪽부터 바깥으로</strong> 한 겹씩 확인합니다. 정전이 났을 때
          우리 집 두꺼비집 → 복도 → 아파트 전체 → 동네 순으로 확인하는 것과 똑같아요.
        </p>
        <svg className="diagram" viewBox="0 0 640 240" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="인터넷 장애 진단 순서 도해. 내 PC는 ipconfig, 공유기는 ping 게이트웨이, 바깥 회선은 ping 8.8.8.8, DNS는 nslookup으로 안쪽에서 바깥쪽 순서로 확인하고, 실패한 지점이 원인이다.">
          <text x="12" y="30" fontSize="12" fill="var(--muted)">안쪽 (나)</text>
          <line x1="104" y1="26" x2="522" y2="26" stroke="var(--muted)" strokeWidth="1" strokeDasharray="4 4" />
          <polyline points="522,21 530,26 522,31" fill="none" stroke="var(--muted)" strokeWidth="1" />
          <text x="628" y="30" textAnchor="end" fontSize="12" fill="var(--muted)">바깥쪽 (상대)</text>
          <rect x="10" y="56" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="60" y="82" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">① 내 PC</text>
          <text x="60" y="104" textAnchor="middle" fontSize="12" fill="var(--primary)">ipconfig</text>
          <rect x="140" y="56" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="190" y="82" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">② 공유기</text>
          <text x="190" y="104" textAnchor="middle" fontSize="12" fill="var(--primary)">ping 게이트웨이</text>
          <rect x="270" y="56" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="320" y="82" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">③ 바깥 회선</text>
          <text x="320" y="104" textAnchor="middle" fontSize="12" fill="var(--primary)">ping 8.8.8.8</text>
          <rect x="400" y="56" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
          <text x="450" y="82" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">④ DNS</text>
          <text x="450" y="104" textAnchor="middle" fontSize="12" fill="var(--primary)">nslookup</text>
          <rect x="530" y="56" width="100" height="64" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
          <text x="580" y="82" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">⑤ 그 사이트</text>
          <text x="580" y="104" textAnchor="middle" fontSize="12" fill="var(--muted)">서버 측 문제</text>
          <text x="125" y="80" textAnchor="middle" fontSize="12" fill="var(--teal)">성공</text>
          <line x1="110" y1="92" x2="133" y2="92" stroke="var(--teal)" strokeWidth="1.5" />
          <polyline points="132,87 140,92 132,97" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
          <text x="255" y="80" textAnchor="middle" fontSize="12" fill="var(--teal)">성공</text>
          <line x1="240" y1="92" x2="263" y2="92" stroke="var(--teal)" strokeWidth="1.5" />
          <polyline points="262,87 270,92 262,97" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
          <text x="385" y="80" textAnchor="middle" fontSize="12" fill="var(--teal)">성공</text>
          <line x1="370" y1="92" x2="393" y2="92" stroke="var(--teal)" strokeWidth="1.5" />
          <polyline points="392,87 400,92 392,97" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
          <text x="515" y="80" textAnchor="middle" fontSize="12" fill="var(--teal)">성공</text>
          <line x1="500" y1="92" x2="523" y2="92" stroke="var(--teal)" strokeWidth="1.5" />
          <polyline points="522,87 530,92 522,97" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
          <line x1="60" y1="120" x2="60" y2="137" stroke="var(--rose)" strokeWidth="1.5" />
          <polyline points="55,136 60,144 65,136" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
          <text x="60" y="164" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--rose)">랜선·WiFi 확인</text>
          <line x1="190" y1="120" x2="190" y2="137" stroke="var(--rose)" strokeWidth="1.5" />
          <polyline points="185,136 190,144 195,136" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
          <text x="190" y="164" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--rose)">공유기 재부팅</text>
          <line x1="320" y1="120" x2="320" y2="137" stroke="var(--rose)" strokeWidth="1.5" />
          <polyline points="315,136 320,144 325,136" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
          <text x="320" y="164" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--rose)">통신사에 연락</text>
          <line x1="450" y1="120" x2="450" y2="137" stroke="var(--rose)" strokeWidth="1.5" />
          <polyline points="445,136 450,144 455,136" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
          <text x="450" y="164" textAnchor="middle" fontSize="12" fontWeight="600" fill="var(--rose)">DNS가 범인</text>
          <text x="320" y="206" textAnchor="middle" fontSize="12" fill="var(--muted)">→ 응답이 오면 오른쪽 다음 단계로 · ↓ 실패하면 그 지점이 범인</text>
        </svg>
        <p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 안쪽(나)에서 바깥쪽(상대)으로 한 겹씩 — 실패한 지점이 곧 원인이다</p>
        <Code>{CODE_FLOWCHART}</Code>
        <p>
          이 순서도의 힘은 <strong>"어디까지는 정상"인지 선을 긋는 것</strong>이에요.
          무작정 "안 돼요"가 아니라 "③까지 통과, ④에서 실패 → DNS 문제"라고 말하는 순간,
          여러분은 문제를 <strong>신고하는 사람</strong>에서 <strong>진단하는 사람</strong>이
          됩니다. 실무에서 신뢰는 이런 데서 쌓여요.
        </p>
        <div className="tip">
          <b>직접 확인해 보기 ⑥</b> 지금은 인터넷이 잘 되죠? 잘 될 때 ①~④를 한 번
          전부 돌려 보고 정상 출력을 눈에 익혀 두세요. 진짜 장애가 났을 때 "평소와 뭐가
          다른지"를 알아보는 게 진단의 절반입니다 — 건강할 때 건강검진 받아 두는 거예요.
        </div>
      </Section>

      <div className="step-card">
        <div className="step-body">
          <h3 style={{ marginBottom: 6 }}>🩺 여기까지 왔다면</h3>
          <p className="muted">
            이제 터미널만으로 서버 생존 확인(ping), 경로 추적(tracert), DNS 질문(nslookup),
            내 주소 확인(ipconfig), 연결 목록(netstat), API 호출(curl)까지 —
            네트워크 청진기 세트를 전부 손에 넣었어요.
          </p>
          <Code>{CODE_CHECKLIST}</Code>
          <p className="muted">
            이 명령들이 오가는 길 자체가 궁금해졌다면{' '}
            <Link to="/learn/network"><strong>네트워크의 이해</strong></Link> 코스에서 랜선부터
            해저 케이블까지의 여행을, curl로 두드려 본 API를 직접 만들어 보고 싶다면{' '}
            <Link to="/learn/coding"><strong>코딩 기초</strong></Link> 코스를 이어서 들어 보세요.
            멘토 과제: 오늘 배운 순서도로 <strong>모의 장애 진단 리포트</strong> 한 장을 써서
            제출해 보기!
          </p>
        </div>
      </div>
    </div>
  );
}
