const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '../../.env') });
const db = require('../db');

const runQuery = async (sql, params = []) => {
    return await db.query(sql, params);
};

// NETWORK SECURITY PATH DATA
const netSecPath = {
    title: "Network Security & Traffic Analysis",
    description: "Master the foundational protocols of the internet and learn how to analyze network traffic to detect and stop cyber attacks.",
    difficulty_level: "intermediate",
    estimated_hours: 50,
    display_order: 6 
};

// MODULE 1 DATA
const module1 = {
    title: "Module 1: TCP/IP & Protocols",
    description: "Understand how computers communicate globally. Learn the OSI model, TCP/IP suite, and fundamental networking concepts.",
    display_order: 1,
    tasks: [
        {
            title: "The OSI & TCP/IP Models",
            xp_reward: 100,
            reading_time: 7,
            content: `# The OSI & TCP/IP Models

To understand how to secure a network, you must first understand how a network functions. When you type \`google.com\` into your browser, a complex sequence of events occurs in milliseconds to fetch that webpage.

Network communication is broken down into theoretical layers. The two main models used to describe this are the **OSI Model** (7 layers) and the practical **TCP/IP Model** (4 layers).

## The OSI Model (Open Systems Interconnection)
This is a conceptual framework used to understand and standardize the functions of a telecommunication system.

1.  **Layer 7: Application** - The layer the user interacts with (HTTP, DNS, SMTP, FTP).
2.  **Layer 6: Presentation** - Data translation, encryption (SSL/TLS), and compression.
3.  **Layer 5: Session** - Establishing, maintaining, and terminating "sessions" between applications.
4.  **Layer 4: Transport** - Reliable vs. unreliable delivery. Where TCP and UDP live. Data is packaged into *Segments*. Ports (like port 80 or 443) operate here.
5.  **Layer 3: Network** - IP Addressing and Routing. How data gets from one network to an entirely different network. Data is packaged into *Packets*. Routers operate here.
6.  **Layer 2: Data Link** - MAC Addressing. How data moves between devices on the *same* local network. Data is packaged into *Frames*. Switches operate here.
7.  **Layer 1: Physical** - The actual cables, radio waves (Wi-Fi), fiber optics, and electrical signals representing 1s and 0s.

## The TCP/IP Model
While the OSI model is great for theory, the internet actually runs on the TCP/IP model, which condenses the 7 layers into 4 practical layers:

1.  **Application Layer** (Combines OSI Layers 5, 6, 7): HTTP, DNS, SSH.
2.  **Transport Layer** (Matches OSI Layer 4): TCP, UDP.
3.  **Internet Layer** (Matches OSI Layer 3): IPv4, IPv6, ICMP.
4.  **Network Access Layer** (Combines OSI Layers 1, 2): Ethernet, Wi-Fi, MAC addresses.

## Encapsulation
When you send an email, the data moves *down* the OSI layers on your computer. 
*   Your email app (L7) passing data to the Transport layer (L4), which adds a TCP header.
*   It goes down to the Network layer (L3), which adds an IP header (Source and Dest IP).
*   It goes down to the Data Link layer (L2), which adds a MAC header.
*   It finally goes out the Physical layer (L1) as electricity across the wire.

When the receiving server gets the electrical signals, it reverses the process, moving *up* the layers (De-encapsulation) until the raw email text reaches the Application layer.`,
            questions: [
                ['How many layers are in the theoretical OSI model?', '7', 1, 'It is a 7-layer model.', 0, ['4', '5', '7', '9']],
                ['Which OSI layer is responsible for logical IP addressing and routing packets between different networks?', 'Layer 3: Network', 2, 'Routers live here.', 0, ['Layer 2: Data Link', 'Layer 3: Network', 'Layer 4: Transport', 'Layer 7: Application']],
                ['TCP and UDP, along with port numbers, operate at which layer of the OSI model?', 'Layer 4: Transport', 3, 'This layer handles end-to-end transport.', 0, ['Layer 2', 'Layer 3', 'Layer 4: Transport', 'Layer 5']],
                ['The process of a higher-layer protocol adding its own header to the payload received from the layer above it, as data moves down the OSI stack, is called what?', 'Encapsulation', 4, 'Putting the data inside a capsule (header).', 0, ['Segmentation', 'De-encapsulation', 'Routing', 'Encapsulation']],
                ['In the simplified TCP/IP model, which single layer combines the functions of the OSI model\'s Session, Presentation, and Application layers?', 'Application Layer', 5, 'The top layer of TCP/IP.', 0, ['Internet Layer', 'Transport Layer', 'Application Layer', 'Network Access Layer']]
            ]
        },
        {
            title: "TCP vs UDP",
            xp_reward: 100,
            reading_time: 6,
            content: `# Transmission Control Protocol vs. User Datagram Protocol

At Layer 4 (the Transport Layer), the two dominant protocols are TCP and UDP. Understanding the difference is crucial for identifying how network attacks work and how Firewalls are configured.

## TCP (Transmission Control Protocol)
TCP is reliable, connection-oriented, and stateful. It guarantees that data will arrive, and in the correct order.

*   **The 3-Way Handshake:** Before ANY data is sent, TCP establishes a strict connection.
    1.  **SYN:** Client says "I'd like to talk to you."
    2.  **SYN-ACK:** Server says "Okay, I acknowledge your request, let's talk."
    3.  **ACK:** Client says "Great, I'm sending data now."
*   **Reliability:** Once connected, every time a computer sends a segment of data, the receiving computer must reply with an acknowledgment (ACK). If the sender doesn't get the ACK (because the packet dropped over Wi-Fi), it will automatically retransmit the data.
*   **Use Cases:** Web Browsing (HTTP/HTTPS), Email (SMTP), File Transfers (FTP/SMB), SSH. If a single byte is missing from a downloaded executable, the file breaks. TCP ensures every byte arrives.

## UDP (User Datagram Protocol)
UDP is unreliable, connectionless, and stateless. It just throws data at the destination and hopes it gets there.

*   **No Handshake:** UDP does not establish a connection first. It just starts sending packets immediately.
*   **No Acknowledgments:** If a packet gets dropped by a router on the internet, it's gone forever. UDP does not resend lost data.
*   **Why use it?** Speed and low overhead. Because there are no handshakes or ACKs, UDP is much faster.
*   **Use Cases:** Live Video Streaming (Zoom, Twitch), VoIP (Phone calls), DNS queries, Online Gaming. If you drop a single frame in a 60fps video game, it doesn't matter, you don't want the game to pause to re-download that old frame. You just proceed to the next current frame.

## Ports
Both TCP and UDP use **Ports** to direct traffic to the right application on a computer. A computer has 1 IP address, but can have up to 65,535 ports open simultaneously. 
*   If traffic arrives at IP 192.168.1.10 on TCP Port 80, the OS hands that data to the Web Server software.
*   If traffic arrives at TCP Port 22, the OS hands it to the SSH Server software.`,
            questions: [
                ['Which transport layer protocol requires a "3-Way Handshake" to establish a connection before any actual data is transmitted?', 'TCP', 1, 'Transmission Control Protocol.', 0, ['UDP', 'ICMP', 'TCP', 'IP']],
                ['What are the three steps, in order, of the TCP 3-Way Handshake?', 'SYN, SYN-ACK, ACK', 2, 'Synchronize, Synchronize-Acknowledge, Acknowledge.', 0, ['ACK, SYN, SYN-ACK', 'SYN, ACK, FIN', 'SYN, SYN-ACK, ACK', 'REQ, RES, ACK']],
                ['Which protocol is connectionless, "fire and forget", and does not guarantee delivery of packets?', 'UDP', 3, 'User Datagram Protocol.', 0, ['TCP', 'UDP', 'FTP', 'SSH']],
                ['Which of the following applications would primarily rely on UDP for its communication?', 'Live VoIP Phone Call', 4, 'Speed over reliability.', 0, ['Downloading a ZIP file', 'Sending an Email', 'Loading a Webpage', 'Live VoIP Phone Call']],
                ['What is the term for the numerical identifier (ranging from 1 to 65535) used at Layer 4 to ensure incoming data is routed to the correct specific application running on a server?', 'Port Number', 5, 'Like an apartment number in a building.', 0, ['IP Address', 'MAC Address', 'Socket', 'Port Number']]
            ]
        },
        {
            title: "Core Protocols & Services",
            xp_reward: 120,
            reading_time: 8,
            content: `# Core Protocols & Services

To detect anomalies, you must know what normal looks like. Attackers constantly abuse these foundational protocols.

## DNS (Domain Name System)
*   **Port:** UDP 53 (and sometimes TCP 53)
*   **Function:** The phonebook of the internet. It translates human-readable domain names (\`infoseclabs.com\`) into machine IP addresses (\`104.21.5.12\`).
*   **Security Context:** Attackers use DNS for Command & Control (C2) beacons, data exfiltration (DNS Tunneling), and redirecting traffic via DNS Spoofing.

## DHCP (Dynamic Host Configuration Protocol)
*   **Port:** UDP 67 (Server) and UDP 68 (Client)
*   **Function:** Automatically assigns IP addresses, Subnet Masks, and Default Gateways to devices when they join a network.
*   **Security Context:** Rogue DHCP servers can assign malicious DNS settings to victim computers, executing Man-In-The-Middle attacks almost invisibly.

## ARP (Address Resolution Protocol)
*   **Layer:** Layer 2 (Data Link) / Layer 3 (Network) boundary.
*   **Function:** Maps an IP address to a physical MAC address on a local network. If computer A (IP 10.0.0.5) wants to talk to the Router (IP 10.0.0.1) on the same Wi-Fi, it shouts "Who has 10.0.0.1?" via ARP. The router replies with its physical MAC address so the switch knows where to send the frame.
*   **Security Context:** **ARP Spoofing**. An attacker can lie and reply to the ARP request saying *they* are the router. The victim then sends all their traffic to the hacker instead of the real router.

## ICMP (Internet Control Message Protocol)
*   **Layer:** Layer 3 (Network)
*   **Function:** Used for network diagnostics and error reporting. It is not used for transferring data between systems. The \`ping\` command and \`traceroute\` commands use ICMP Echo Requests and Echo Replies.
*   **Security Context:** Attackers use ICMP for "Ping Sweeps" to map out live hosts on a network. It can also be abused for ICMP tunneling to bypass firewalls or launch Smurf DDoS attacks.

## HTTP/HTTPS (Hypertext Transfer Protocol)
*   **Port:** TCP 80 (HTTP) and TCP 443 (HTTPS)
*   **Function:** Foundation of the World Wide Web. Facilitates downloading web pages, submitting forms (POST), and API communication. HTTPS adds a layer of encryption (TLS/SSL) to secure the data in transit.
*   **Security Context:** The vast majority of malware C2 traffic hides inside HTTPS, blending in with regular employee web browsing to evade detection by firewalls.`,
            questions: [
                ['Which protocol translates human-readable domain names like "google.com" into IP addresses?', 'DNS', 1, 'Domain Name System.', 0, ['DHCP', 'ARP', 'DNS', 'HTTP']],
                ['Which protocol is responsible for automatically distributing IP addresses and network configurations to laptops and phones connecting to a Wi-Fi network?', 'DHCP', 2, 'Dynamic Host Configuration Protocol.', 0, ['DNS', 'BGP', 'ICMP', 'DHCP']],
                ['If an attacker wants to perform a local Man-in-the-Middle attack by tricking a victim computer into believing the attacker\'s MAC address actually belongs to the Default Gateway, what protocol are they abusing?', 'ARP', 3, 'Address Resolution Protocol.', 0, ['ICMP', 'ARP', 'DNS', 'TCP']],
                ['The "ping" command line utility utilizes which Layer 3 diagnostic protocol to determine if a remote server is online?', 'ICMP', 4, 'Internet Control Message Protocol.', 0, ['TCP', 'UDP', 'IGMP', 'ICMP']],
                ['Why do modern malware developers primarily design their Command and Control (C2) communication to use HTTPS (TCP port 443)?', 'To blend in with normal web traffic and bypass restrictive corporate firewalls', 5, 'It looks like regular encrypted browsing.', 0, ['Because it is the fastest protocol available', 'To blend in with normal web traffic and bypass restrictive corporate firewalls', 'Because UDP is unreliable', 'Because HTTPS traffic is not recorded by ISPs']]
            ]
        }
    ]
};

// MODULE 2 DATA
const module2 = {
    title: "Module 2: Traffic Analysis (Wireshark)",
    description: "Learn how to use Wireshark to inspect packets, filter traffic, and reconstruct network events.",
    display_order: 2,
    tasks: [
        {
            title: "Navigating Wireshark",
            xp_reward: 100,
            reading_time: 7,
            content: `# Navigating Wireshark

Wireshark is the industry standard for network protocol analysis. It allows you to see what's happening on your network at a microscopic level. It is the de facto standard across many commercial and non-profit enterprises, government agencies, and educational institutions.

## The GUI Layout
When you open a packet capture (PCAP) in Wireshark, the interface is divided into three main panes:

1.  **Packet List Pane (Top):** This pane displays a summary of each packet captured. By default, it shows the packet number, time, source IP address, destination IP address, protocol, length, and detailed information. Clicking on a packet in this pane controls what is displayed in the other two panes.
2.  **Packet Details Pane (Middle):** This pane shows the current packet, broken down layer by layer, closely mirroring the OSI and TCP/IP models. You can expand each layer (e.g., Ethernet II, IPv4, TCP) to see the specific hex values and how Wireshark interprets them.
3.  **Packet Bytes Pane (Bottom):** This pane displays the raw, uninterpreted data of the selected packet in hexadecimal and ASCII format. When you select a field in the *Details Pane*, the corresponding bytes are highlighted in the *Bytes Pane*.

## Basic Navigation and Sorting
*   **Time Column:** By default, the Time column shows the seconds since the beginning of the capture. You can change this via \`View -> Time Display Format\` to show the actual Time of Day (e.g., \`14:32:05.123\`).
*   **Sorting:** You can click on the headers in the Packet List pane to sort by Source IP, Destination IP, Protocol, or Length. This is useful for quickly finding the largest packets or sorting traffic by protocol.
*   **Finding Packets:** You can use \`Ctrl+F\` (or \`Cmd+F\`) to search for specific strings, hex values, or display filters within the current capture.

## Color Coding
Wireshark uses color-coding to help you quickly identify different types of traffic.
*   **Green:** Typically, HTTP or routing traffic.
*   **Light Blue:** UDP traffic (like DNS lookups).
*   **Dark Blue/Purple:** TCP traffic.
*   **Black/Red:** Packets with errors, warnings, or bad checksums (e.g., a TCP Retransmission or out-of-order packet).

*Note: You can customize these coloring rules in \`View -> Coloring Rules\`.*`,
            questions: [
                ['In the Wireshark GUI, which pane displays the raw hexadecimal and ASCII representation of the packet?', 'Packet Bytes Pane (Bottom)', 1, 'The lowest pane shows the rawest data.', 0, ['Packet List Pane (Top)', 'Packet Details Pane (Middle)', 'Packet Bytes Pane (Bottom)', 'Filter Pane']],
                ['Which Wireshark pane allows you to expand protocol headers layer by layer (e.g., expanding the IPv4 header to see the TTL value)?', 'Packet Details Pane (Middle)', 2, 'It breaks down the details of the protocol.', 0, ['Packet List Pane (Top)', 'Packet Details Pane (Middle)', 'Packet Bytes Pane (Bottom)', 'Status Bar']],
                ['By default, what does the "Time" column in the Packet List pane display?', 'Seconds since the beginning of the capture', 3, 'It is relative time by default.', 0, ['The actual Time of Day (e.g., 14:00:00)', 'Seconds since the beginning of the capture', 'Milliseconds since the computer booted', 'Remaining time until the capture ends']],
                ['If you want to quickly organize the Packet List pane to show the largest packets at the top, what action should you take?', 'Click on the "Length" column header to sort', 4, 'Sorting by columns.', 0, ['Write a complex display filter', 'Use the Find feature (Ctrl+F)', 'Click on the "Length" column header to sort', 'Change the Color Rules']],
                ['In Wireshark\'s default color scheme, what do packets colored with black backgrounds and bright red text typically indicate?', 'Errors, warnings, or bad checksums (like TCP Retransmissions)', 5, 'Red usually means bad news or errors.', 0, ['Normal HTTP Web Traffic', 'Successfully established connections', 'Errors, warnings, or bad checksums (like TCP Retransmissions)', 'Encrypted SSH traffic']]
            ]
        },
        {
            title: "Mastering Display Filters",
            xp_reward: 120,
            reading_time: 8,
            content: `# Mastering Display Filters

PCAP files often contain hundreds of thousands or even millions of packets. Manually scrolling through them is impossible. **Display Filters** are your strongest weapon as an analyst to cut through the noise and find the signal.

*Important:* Do not confuse Display Filters with Capture Filters. Capture filters decide what data gets written to disk. Display filters hide/show data that has already been captured.

## Filter Syntax Basics
Wireshark uses a very specific syntax for filtering.

*   \`.==\` (Equals): \`ip.addr == 192.168.1.100\`
*   \`.!=\` (Not Equals): \`ip.src != 10.0.0.5\`
*   \`.>\` (Greater Than): \`frame.len > 1500\`

## IP and Protocol Filtering
*   **By IP Address:**
    *   \`ip.src == 8.8.8.8\` (Shows only packets originating *from* 8.8.8.8)
    *   \`ip.dst == 8.8.8.8\` (Shows only packets going *to* 8.8.8.8)
    *   \`ip.addr == 8.8.8.8\` (Shows packets where 8.8.8.8 is *either* the source or destination)
*   **By Protocol:** Just type the protocol name.
    *   \`http\`
    *   \`dns\`
    *   \`tcp\`
*   **By Port:**
    *   \`tcp.port == 443\` (Shows HTTPS traffic)
    *   \`udp.port == 53\` (Shows DNS traffic)

## Boolean Operators (Combining Filters)
To find highly specific events, you must chain filters together.

*   **AND (\`&&\`):** Both conditions must be true.
    *   \`ip.src == 192.168.1.50 && tcp.port == 80\` (Finds HTTP traffic originating from a specific laptop).
*   **OR (\`||\`):** Only one condition needs to be true.
    *   \`tcp.port == 80 || tcp.port == 443\` (Shows both HTTP and HTTPS traffic).
*   **NOT (\`!\`):** Excludes traffic.
    *   \`ip.addr == 192.168.1.50 && !(dns)\` (Shows all traffic for that IP *except* DNS queries).

## Advanced Filtering (Contains and Matches)
*   **Contains:** Searches for a specific string payload inside the packets.
    *   \`http contains "password"\` (Searches all unencrypted HTTP packets for the word "password").
*   **Matches:** Uses Regular Expressions (Regex) for powerful pattern matching.
    *   \`http.host matches "\.(cn|ru)$"\` (Finds HTTP traffic going to Russian or Chinese top-level domains).`,
            questions: [
                ['What is the fundamental difference between a Capture Filter and a Display Filter in Wireshark?', 'Capture filters determine what is saved to disk; Display filters hide/show data already saved', 1, 'One records, the other views.', 0, ['Capture filters are applied after recording; Display filters are applied before', 'Capture filters determine what is saved to disk; Display filters hide/show data already saved', 'There is no difference, they are the same thing', 'Capture filters only work on Linux; Display filters only work on Windows']],
                ['Which display filter correctly shows traffic where the source IP address is exactly 10.0.0.100?', 'ip.src == 10.0.0.100', 2, 'Remember the double equals and .src notation.', 0, ['ip.addr = 10.0.0.100', 'source_ip == 10.0.0.100', 'ip.src == 10.0.0.100', 'ip_src := 10.0.0.100']],
                ['If an analyst wants to view all traffic for IP 192.168.1.5 that is NOT DNS traffic, which filter should they use?', 'ip.addr == 192.168.1.5 && !(dns)', 3, 'Combine AND with NOT.', 0, ['ip.addr == 192.168.1.5 || !(dns)', 'ip.addr == 192.168.1.5 && dns == 0', 'ip.addr == 192.168.1.5 && !(dns)', 'ip.addr = 192.168.1.5 AND NOT dns']],
                ['Which operator allows you to search for a specific, literal text string within the payload of a packet, such as `http _______ "login"`?', 'contains', 4, 'It checks if the payload contains the string.', 0, ['has', 'matches', 'includes', 'contains']],
                ['To show traffic targeting either the standard HTTP port OR the standard HTTPS port, which filter is correct?', 'tcp.port == 80 || tcp.port == 443', 5, 'Use the boolean OR operator.', 0, ['tcp.port == 80 && tcp.port == 443', 'tcp.port == 80 || tcp.port == 443', 'tcp.ports = 80, 443', 'http || https']]
            ]
        },
        {
            title: "Following Streams & Object Extraction",
            xp_reward: 110,
            reading_time: 7,
            content: `# Following Streams & Object Extraction

When an attacker downloads malware via HTTP, or an employee uploads a confidential PDF via FTP, that data is split into hundreds of separate TCP segments. Looking at one packet at a time is useless for understanding the "big picture."

## Follow TCP Stream
This is arguably Wireshark's most powerful feature for reconstructing events.

If you right-click a packet that is part of a larger conversation (like an HTTP GET request) and select **Follow -> TCP Stream**, Wireshark performs magic:
1.  It automatically figures out the source/dest IPs and ports.
2.  It reassembles all the fragmented packets in the correct order.
3.  It strips away all the OSI headers (MAC, IP, TCP headers).
4.  It presents you with a clean text window showing *only* the application layer data.

**Reading the Stream:**
*   Text colored **Red** represents data sent from the Client to the Server (e.g., the browser asking "GET /index.html").
*   Text colored **Blue** represents data sent from the Server to the Client (e.g., the server replying "200 OK" and the HTML code).

*Note:* If you "Follow" a stream of an encrypted protocol like HTTPS or SSH, you will just see gibberish characters, because the payload is encrypted.

## Extracting Objects
If you can see a file (like an image, a PDF, or an .exe) being downloaded over an unencrypted protocol (HTTP, FTP, SMB), Wireshark can carve that file right out of the PCAP and save it to your hard drive so you can analyze it.

**How to Extract (HTTP):**
1.  Go to **File -> Export Objects -> HTTP...**
2.  Wireshark will open a window listing every single file transferred over HTTP during the entire packet capture.
3.  It lists the Packet Number, Hostname, Content Type (e.g., \`image/png\` or \`application/x-msdownload\`), and the Filename.
4.  You can select a suspicious file and click **"Save"** to put it on your Desktop. You can then submit that file to VirusTotal or analyze it in a sandbox.

This is a critical skill for extracting malware payloads that defense sensors may have missed, but the packet capture recorded.`,
            questions: [
                ['When you "Follow TCP Stream" in Wireshark, what does the software essentially do?', 'Reassembles fragmented packets in order and strips away networking headers to show the raw application data', 1, 'It pieces the conversation back together.', 0, ['Decrypts all HTTPS traffic automatically', 'Deletes all packets that are not part of the stream', 'Runs a malware scan on the packets', 'Reassembles fragmented packets in order and strips away networking headers to show the raw application data']],
                ['When viewing a followed TCP Stream window, what does the RED colored text signify?', 'Data sent from the Client to the Server', 2, 'Red is client requests.', 0, ['Data sent from the Server to the Client', 'Data that failed a checksum', 'Data sent from the Client to the Server', 'Data that triggered an IDS alert']],
                ['If you try to "Follow TCP Stream" on an SSH connection (Port 22), what will you see in the stream window?', 'Random, unreadable gibberish characters', 3, 'SSH is fully encrypted.', 0, ['The username and password in plaintext', 'Random, unreadable gibberish characters', 'A list of files on the server', 'The bash history of the user']],
                ['Which menu path allows you to quickly carve and rebuild a downloaded executable file out of an unencrypted web browsing session?', 'File -> Export Objects -> HTTP', 4, 'Exporting HTTP objects.', 0, ['Edit -> Find Packet -> Executable', 'Analyze -> Decode As -> File', 'Statistics -> Protocol Hierarchy', 'File -> Export Objects -> HTTP']],
                ['When exporting HTTP objects, what information does Wireshark use to try and determine what type of file it is (e.g., telling you it is `application/x-msdownload`)?', 'The Content-Type HTTP header field', 5, 'The server tells the client what type of content it is.', 0, ['The file extension in the URL', 'The Content-Type HTTP header field', 'The MAC address of the server', 'The TCP Sequence Number']]
            ]
        }
    ]
};

// MODULE 3 DATA
const module3 = {
    title: "Module 3: Network Attacks (Spoofing, MITM)",
    description: "Understand how attackers exploit network protocols to intercept data, redirect traffic, and disrupt services.",
    display_order: 3,
    tasks: [
        {
            title: "ARP Spoofing & Poisoning",
            xp_reward: 110,
            reading_time: 7,
            content: `# ARP Spoofing & Poisoning

The Address Resolution Protocol (ARP) is fundamentally insecure by design because it is a "stateless" and "trusting" protocol. It was built in the early days of networking when everyone on a local network trusted each other.

## How Normal ARP Works
As a reminder, ARP operates at Layer 2 (Data Link). When your computer (IP: \`10.0.0.5\`) wants to send a packet to the internet, it must first send it to your Default Gateway (the Router, IP: \`10.0.0.1\`). However, switches don't understand IP addresses; they only understand physical MAC addresses.

1.  Your computer shouts out to the entire network: *"Who has IP 10.0.0.1? Tell 10.0.0.5."*
2.  The Router (\`10.0.0.1\`) replies directly to your computer: *"I am 10.0.0.1, and my MAC address is AA:BB:CC:DD:EE:FF."*
3.  Your computer saves this mapping in its temporary **ARP Cache**.

## The Attack: ARP Spoofing
The flaw in ARP is that an attacker can send out an **ARP Reply** *even if no one asked for it* (this is called a Gratuitous ARP). Furthermore, devices will gladly accept this unsolicited reply and update their ARP cache without any verification.

**The Scenario:**
Let's say the Hacker's MAC address is \`66:66:66:66:66:66\`.

1.  The attacker sends a forged ARP Reply to the Victim (\`10.0.0.5\`) saying: *"Hey, the Router (10.0.0.1) is now at MAC 66:66:66:66:66:66."*
2.  The Victim's computer blindly trusts this and updates its ARP cache.
3.  The attacker also sends a forged ARP Reply to the true Router (\`10.0.0.1\`) saying: *"Hey, the Victim (10.0.0.5) is now at MAC 66:66:66:66:66:66."*
4.  The Router blindly trusts this and updates its ARP cache.

## The Result: Man-in-the-Middle (MITM)
Because the attacker has "poisoned" the ARP cache of both the Victim and the Router, all traffic flowing between them now routes directly through the attacker's machine. 

The attacker can now:
*   **Packet Sniff:** Read unencrypted traffic (HTTP, FTP, Telnet) in real-time, stealing passwords and session cookies.
*   **Packet Modify:** Alter the traffic in transit (e.g., replacing a legitimate software download with a malware payload).
*   **Denial of Service (DoS):** Simply drop all the packets from the victim, disconnecting them from the internet (a "Blackhole" attack).

*Note: ARP Spoofing only works on the LOCAL network (LAN). An attacker in Russia cannot ARP Spoof a victim in New York, because MAC addresses do not cross routers.*`,
            questions: [
                ['What fundamental flaw in the Address Resolution Protocol allows ARP spoofing to occur?', 'Devices blindly accept and cache unsolicited ARP replies without any verification', 1, 'ARP is overly trusting.', 0, ['ARP packets are encrypted using a weak algorithm', 'Devices blindly accept and cache unsolicited ARP replies without any verification', 'ARP relies on UDP which does not guarantee delivery', 'ARP broadcasts are dropped by modern network switches']],
                ['In an ARP spoofing attack, what specific hardware identifier is the attacker attempting to associate with a legitimate IP address?', 'Their own MAC address', 2, 'Layer 2 is all about MAC addresses.', 0, ['A randomly generated IPv6 address', 'The switch\'s port number', 'Their own MAC address', 'The default gateway\'s public IP address']],
                ['When an attacker successfully poisons the ARP cache of a victim and a router, putting themselves in the middle of the communication, what type of attack is this?', 'Man-in-the-Middle (MITM)', 3, 'The attacker is literally standing in the middle.', 0, ['Cross-Site Scripting (XSS)', 'Denial of Service (DoS)', 'Man-in-the-Middle (MITM)', 'SQL Injection']],
                ['Can an attacker on the public internet (e.g., in another country) perform an ARP spoofing attack against your home computer?', 'No, ARP operates at Layer 2 and MAC broadcasts do not cross routers into the internet', 4, 'ARP is strictly local.', 0, ['Yes, if they know your public IP address', 'Yes, if they send enough ARP replies to overwhelm your router', 'No, ARP operates at Layer 2 and MAC broadcasts do not cross routers into the internet', 'No, because modern ISPs block all ARP traffic globally']],
                ['If an attacker achieves a MITM position via ARP spoofing and decides to simply drop every packet the victim sends, effectively cutting off their internet access, what is this specific outcome called?', 'A Blackhole or Denial of Service attack', 5, 'Traffic goes in but never comes out.', 0, ['A DNS Amplification attack', 'A Blackhole or Denial of Service attack', 'A Smurf attack', 'A Replay attack']]
            ]
        },
        {
            title: "DNS Spoofing & Hijacking",
            xp_reward: 120,
            reading_time: 8,
            content: `# DNS Spoofing & Hijacking

If ARP Spoofing redirects traffic based on physical MAC addresses, DNS Spoofing redirects traffic based on human-readable domain names. 

The Domain Name System (DNS) translates a website name like \`bank.com\` into the server's IP address (e.g., \`192.0.2.50\`). If an attacker can manipulate this translation process, they control where the user goes.

## Local DNS Spoofing (via MITM)
This is usually the next step after an attacker has successfully executed an ARP Spoofing Man-in-the-Middle attack.

1.  The victim types \`www.bank.com\` into their browser.
2.  The victim's computer sends a DNS Query asking for the IP of \`bank.com\`.
3.  Because the attacker is actively performing a MITM attack via ARP Spoofing, that DNS Query flows through the attacker's machine.
4.  The attacker intercepts the query and sends a fake DNS Reply back to the victim, claiming that \`bank.com\` is located at the Attacker's IP address (e.g., \`10.0.0.66\`).
5.  The victim's browser connects to the Attacker's web server, which is hosting a perfect, pixel-for-pixel fake clone of the bank's login page. 

The victim sees \`www.bank.com\` in the URL bar, but they are secretly typing their credentials into the attacker's database.

## DNS Cache Poisoning (Server-Side)
This is a much larger scale attack. Instead of attacking a single victim, the attacker targets a recursive DNS server (like the one operated by your ISP, or even a public one like Google's \`8.8.8.8\`).

The attacker exploits vulnerabilities in the DNS server software (like BIND) to inject fake records into the server's cache.
If successful, *everyone* who relies on that DNS server will be redirected to the malicious site when they try to visit \`bank.com\`. This affects thousands or millions of users simultaneously.

## Defending Against DNS Attacks
Because classic DNS operates over unencrypted UDP Port 53, it is highly vulnerable to tampering.
*   **DNSSEC (DNS Security Extensions):** Adds cryptographic digital signatures to DNS records. When your computer looks up \`bank.com\`, the true owner of \`bank.com\` signs the response with a private key. Your computer verifies the signature with a public key. If an attacker modifies the IP address in transit, the signature breaks, and your computer drops the fake response.
*   **DoH / DoT (DNS over HTTPS / TLS):** Encrypts the entire DNS conversation so a local MITM attacker cannot even see what domain you are querying, let alone modify the response.`,
            questions: [
                ['In a local DNS Spoofing attack, what must the attacker typically accomplish first in order to intercept the victim\'s DNS queries?', 'Establish a Man-in-the-Middle (MITM) position, usually via ARP Spoofing', 1, 'You need to be in the path of the traffic first.', 0, ['Guess the victim\'s password', 'Hack the corporate firewall', 'Establish a Man-in-the-Middle (MITM) position, usually via ARP Spoofing', 'Perform a Distributed Denial of Service (DDoS)']],
                ['What is the primary goal of a malicious actor performing DNS Spoofing against a user navigating to their online bank?', 'To redirect the user to a fake clone of the bank website to steal their login credentials', 2, 'Phishing via technical redirection.', 0, ['To make the bank website load faster', 'To permanently delete the bank\'s DNS records', 'To redirect the user to a fake clone of the bank website to steal their login credentials', 'To encrypt the user\'s hard drive for ransom']],
                ['How does DNS Cache Poisoning differ from local DNS Spoofing?', 'Cache poisoning targets the DNS Server itself, affecting all users of that server, rather than a single local victim', 3, 'Mass scale vs targeted scale.', 0, ['Cache poisoning only works on IPv6 networks', 'Cache poisoning targets the DNS Server itself, affecting all users of that server, rather than a single local victim', 'Cache poisoning replaces the MAC address instead of the IP address', 'There is no difference; they are synonymous terms']],
                ['Which security technology provides cryptographic digital signatures to verify that the IP address in a DNS reply actually came from the true owner of the domain?', 'DNSSEC', 4, 'DNS Security Extensions.', 0, ['HTTPS', 'VPN', 'DNSSEC', 'WPA3']],
                ['What protocol encrypts DNS queries to prevent local attackers (like someone sniffing traffic at a coffee shop) from seeing or modifying which websites you are trying to visit?', 'DoH (DNS over HTTPS)', 5, 'Hiding DNS inside encrypted web traffic.', 0, ['FTP', 'DoH (DNS over HTTPS)', 'ICMP', 'DHCP']]
            ]
        },
        {
            title: "Network Denial of Service (DoS)",
            xp_reward: 100,
            reading_time: 6,
            content: `# Network Denial of Service (DoS)

A Denial of Service (DoS) attack aims to make a machine or network resource unavailable to its intended users. It does not aim to steal data, but rather to disrupt operations. A Distributed Denial of Service (DDoS) attack uses a botnet (thousands of compromised computers) to execute the attack simultaneously.

## Layer 4: SYN Flood
This attack exploits the stateful nature of the TCP 3-Way Handshake.

*   The attacker sends a massive flood of **SYN** requests (Step 1) to a web server.
*   The server replies to each with a **SYN-ACK** (Step 2) and leaves a "half-open" connection waiting in its memory for the final **ACK** (Step 3).
*   The attacker intentionally *never* sends the final ACK. Sometimes they even spoof the source IP address of the initial SYN, so the server is sending the SYN-ACK to a random, offline IP.
*   **The Result:** The web server's memory fills up with thousands of half-open connections. Eventually, it runs out of resources and drops legitimate new connections from real customers.

## Layer 3 & 4: Amplification/Reflection Attacks
Attackers love "Amplification" attacks because they act as a force multiplier. They send a tiny request and generate a massive response aimed at the victim. This relies on connectionless UDP protocols.

**The Smurf Attack (ICMP):**
1.  The attacker sends an ICMP Echo Request (Ping) to a network's broadcast address (e.g., \`192.168.1.255\`).
2.  However, the attacker *spoofs* the source IP Address of the ping to be the Victim's IP address.
3.  Every single computer on that network (maybe 200 machines) receives the ping, and all 200 simultaneously reply with an ICMP Echo Reply directed at the Victim.
4.  One tiny packet from the attacker generated 200 packets hitting the victim.

**DNS/NTP Amplification:**
1.  The attacker sends a tiny UDP DNS Query (like "give me all records for this domain") to an open DNS server on the internet.
2.  They spoof the source IP to be the Victim's IP.
3.  The DNS server generates a massive response (sometimes 50x larger than the request) and blasts it at the Victim.
4.  Using a botnet, the attacker directs thousands of open DNS servers to reflect massive chunks of traffic at the victim, saturating their internet connection completely.`,
            questions: [
                ['In a TCP SYN Flood attack, which step of the 3-Way Handshake does the attacker intentionally fail to complete in order to consume server resources?', 'The final ACK', 1, 'Leaving connections half-open.', 0, ['The initial SYN', 'The SYN-ACK response', 'The FIN packet', 'The final ACK']],
                ['What is the primary characteristic of an "Amplification" or "Reflection" DoS attack?', 'Sending a small spoofed request that results in a much larger response directed at the victim', 2, 'It acts as a force multiplier for the attacker.', 0, ['Encrypting the server\'s hard drive to prevent access', 'Sending a small spoofed request that results in a much larger response directed at the victim', 'Exploiting a buffer overflow in the web application code', 'Guessing the administrator\'s password millions of times per minute']],
                ['Why do Amplification attacks almost exclusively rely on UDP protocols like DNS or NTP, rather than TCP?', 'UDP is connectionless and stateless, making it easy to spoof the source IP address', 3, 'TCP\'s handshake prevents spoofed source IPs from establishing connections.', 0, ['UDP packets are naturally larger than TCP packets', 'UDP is heavily encrypted making it harder to track', 'UDP is connectionless and stateless, making it easy to spoof the source IP address', 'TCP is immune to all forms of Denial of Service']],
                ['In a historic "Smurf Attack", what protocol does the attacker abuse by sending packets to a broadcast address with a spoofed source IP?', 'ICMP (Ping)', 4, 'It uses Echo Requests and Replies.', 0, ['HTTP', 'SMTP', 'ICMP (Ping)', 'DHCP']],
                ['What distinguishes a DDoS attack from a standard DoS attack?', 'DDoS utilizes multiple compromised systems (a botnet) to launch the attack simultaneously', 5, 'Distributed means coming from many places at once.', 0, ['DDoS relies on physical destruction of servers', 'DDoS only targets government networks', 'DDoS utilizes multiple compromised systems (a botnet) to launch the attack simultaneously', 'DDoS attacks steal data, whereas DoS attacks only disrupt service']]
            ]
        }
    ]
};

// MODULE 4 DATA
const module4 = {
    title: "Module 4: Firewalls & IDS/IPS",
    description: "Learn how to defend networks using Firewalls, Intrusion Detection Systems, and Intrusion Prevention Systems.",
    display_order: 4,
    tasks: [
        {
            title: "Firewalls: The First Line of Defense",
            xp_reward: 100,
            reading_time: 7,
            content: `# Firewalls: The First Line of Defense

A firewall is a network security device that monitors and filters incoming and outgoing network traffic based on an organization's previously established security policies. It acts as the barrier between a trusted internal network and an untrusted external network (like the internet).

## Types of Firewalls
Firewalls have evolved significantly over the years, moving higher up the OSI model to provide better security.

### 1. Packet-Filtering Firewalls (Stateless)
*   **Operating Layer:** Layer 3 (Network) & Layer 4 (Transport).
*   **How it works:** It looks at each individual packet in isolation. It checks the Source IP, Destination IP, Protocol, Source Port, and Destination Port against a list of rules (Access Control Lists or ACLs).
*   **Pros:** Extremely fast and requires very little CPU power.
*   **Cons:** "Stateless" means it has no memory of the connection. If you allow traffic OUT on port 80, you also have to manually write a rule allowing traffic IN from port 80 so the website can reply. This is tedious and insecure. It also cannot look inside the packet payload, so a malicious command sent over an allowed port (like HTTP 80) will pass right through.

### 2. Stateful Inspection Firewalls
*   **Operating Layer:** Layer 3 & Layer 4 (with session tracking).
*   **How it works:** This is the standard modern firewall. It tracks the *state* of active connections. If an internal user initiates an outbound HTTP request, the firewall remembers this "state." When the web server replies, the firewall automatically allows the inbound traffic because it belongs to an established, tracked session.
*   **Pros:** Much more secure than stateless. You only need to write rules for the *initiation* of traffic.
*   **Cons:** Still primarily focuses on IP addresses and ports, not the actual application data.

### 3. Next-Generation Firewalls (NGFW)
*   **Operating Layer:** Up to Layer 7 (Application).
*   **How it works:** NGFWs (like Palo Alto, Fortinet, Cisco Firepower) do everything a stateful firewall does, but they also perform **Deep Packet Inspection (DPI)**. They look *inside* the payload of the packet.
*   **Pros:** They understand applications, not just ports. An NGFW can differentiate between a user browsing Facebook (which might be allowed) and a user trying to play a game on Facebook (which might be blocked), even though both use HTTPS on Port 443. They also include built-in antivirus, intrusion prevention, and SSL decryption capabilities.

## Default Deny Posture
The most fundamental rule of configuring *any* firewall is **Implicit Deny** or **Default Deny**. 
This means you must explicitly define exactly what traffic is *allowed*. If traffic does not match an explicit "Allow" rule, the firewall drops it by default. 

**Deny vs Reject:**
*   **Drop/Deny:** The firewall silently discards the packet. The sender gets no response, making it look like the IP address doesn't even exist. This is best practice for internet-facing interfaces to frustrate scanners.
*   **Reject:** The firewall discards the packet but sends a polite "Connection Refused" (ICMP Destination Unreachable or TCP RST) back to the sender. This is sometimes used on internal networks for easier troubleshooting.`,
            questions: [
                ['Which type of firewall looks at every single packet individually and has no memory of the overall connection or "session"?', 'Stateless Packet-Filtering Firewall', 1, 'It lacks state awareness.', 0, ['Stateful Inspection Firewall', 'Next-Generation Firewall (NGFW)', 'Stateless Packet-Filtering Firewall', 'Web Application Firewall (WAF)']],
                ['If an internal employee initiates an outbound connection to a web server, what feature allows a modern firewall to automatically permit the returning inbound web traffic without requiring a specific inbound "allow" rule?', 'Stateful Inspection', 2, 'Tracking the state of the connection.', 0, ['Stateless Filtering', 'Stateful Inspection', 'Deep Packet Inspection', 'SSL Decryption']],
                ['Next-Generation Firewalls (NGFWs) operate up to which layer of the OSI model, allowing them to understand specific applications like "Facebook" or "BitTorrent" rather than just "Port 443"?', 'Layer 7 (Application Layer)', 3, 'The highest layer for application awareness.', 0, ['Layer 3 (Network Layer)', 'Layer 4 (Transport Layer)', 'Layer 5 (Session Layer)', 'Layer 7 (Application Layer)']],
                ['What is the fundamental security principle that dictates a firewall should block all traffic unless a specific rule has been created to explicitly allow it?', 'Implicit Deny / Default Deny', 4, 'Assume everything is bad until proven good.', 0, ['Implicit Allow', 'Default Reject', 'Implicit Deny / Default Deny', 'Least Privilege Routing']],
                ['When a firewall blocks traffic coming from the public internet, which action is generally preferred because it silently discards the packet without giving the attacker any feedback or confirmation that the IP address is active?', 'Drop (or Deny)', 5, 'Silence is golden when dealing with scanners.', 0, ['Reject', 'Drop (or Deny)', 'Forward', 'Proxy']]
            ]
        },
        {
            title: "IDS vs IPS",
            xp_reward: 110,
            reading_time: 7,
            content: `# Intrusion Detection vs. Intrusion Prevention

While firewalls enforce policy based on *who* is talking to *who*, Intrusion Detection Systems (IDS) and Intrusion Prevention Systems (IPS) look for malicious *behavior* or known bad *signatures* within the traffic.

## Intrusion Detection System (IDS)
An IDS is a **passive** monitoring system. It is the security equivalent of a burglar alarm. 

*   **How it connects:** It is normally connected to a "SPAN port" or "Mirror port" on a network switch. The switch sends a *copy* of all network traffic to the IDS. The original traffic flows uninterrupted to its destination.
*   **Action:** When the IDS detects a threat (e.g., an SQL injection payload inside an HTTP request), it generates an alert and sends it to the SIEM for the SOC team to review.
*   **Pros:** Because it sits out-of-band (analyzing a copy), an IDS can never accidentally block legitimate traffic (no false positive blocks). If the IDS crashes, network traffic continues to flow normally.
*   **Cons:** It cannot stop an attack. It only alerts you that an attack is currently happening or has already succeeded. The attack traffic still reaches the target server.

## Intrusion Prevention System (IPS)
An IPS is an **active** defense system. It is the security equivalent of an armed guard at the door.

*   **How it connects:** It is deployed **in-line** with the traffic. All traffic *must* physically flow through the IPS device before reaching the internal network or servers.
*   **Action:** When the IPS detects a threat, it doesn't just generate an alert; it actively **drops the malicious packets**, resets the TCP connection, and blocks the attacker's IP address in real-time.
*   **Pros:** It actually stops attacks before they reach the vulnerable server.
*   **Cons:** Because it sits in-line, a false positive is disastrous. If the IPS mistakes a legitimate customer uploading a legitimate document for a malware attack, it drops the connection, causing a business outage. Furthermore, if an in-line IPS crashes, all network traffic stops unless it fails "open" (which brings its own security risks).

## Detection Methods
Both IDS and IPS use two primary methods to find evil:

1.  **Signature-Based:** Works exactly like traditional antivirus. It looks for a specific string of bytes (a signature) known to belong to a specific threat, like the "EternalBlue" exploit. It is highly accurate but cannot detect brand new, never-before-seen (Zero-Day) attacks because no signature exists yet.
2.  **Anomaly/Behavior-Based:** Uses machine learning and statistical baselines to learn what "normal" network traffic looks like over several weeks. If suddenly the database server starts downloading 50GB of data at 3 AM (which it has never done before), the system flags it as anomalous. This *can* catch Zero-Day attacks, but suffers from a much higher rate of False Positives because networks are inherently unpredictable.`,
            questions: [
                ['Which system operates passively by analyzing a copy of network traffic (out-of-band) and only generates alerts without blocking the traffic?', 'IDS (Intrusion Detection System)', 1, 'It detects, but does not prevent.', 0, ['IPS (Intrusion Prevention System)', 'NGFW (Next-Generation Firewall)', 'IDS (Intrusion Detection System)', 'WAF (Web Application Firewall)']],
                ['Because an Intrusion Prevention System (IPS) sits "in-line" with network traffic, what is the most significant operational risk if it is misconfigured?', 'It might accidentally drop legitimate business traffic (a False Positive block)', 2, 'Active inline blocking carries the risk of business disruption.', 0, ['It will slow down the network by copying traffic to a span port', 'It cannot detect encrypted traffic at all', 'It might accidentally drop legitimate business traffic (a False Positive block)', 'It will automatically grant administrator rights to external IP addresses']],
                ['If a brand new, never-before-seen exploit (a Zero-Day) is launched against a network, which detection method is completely blind to it because it relies on known technical indicators?', 'Signature-Based Detection', 3, 'Signatures only work for known past threats.', 0, ['Anomaly-Based Detection', 'Behavioral Analysis', 'Heuristic Detection', 'Signature-Based Detection']],
                ['Which detection method creates a statistical baseline of "normal" traffic and alerts when deviations occur, such as an unusual spike in outbound data transfer at 3 AM?', 'Anomaly/Behavior-Based Detection', 4, 'It looks for weird behavior, not specific bad code.', 0, ['Signature-Based Detection', 'Stateful Inspection', 'Packet Filtering', 'Anomaly/Behavior-Based Detection']],
                ['If an organization values "never accidentally dropping a legitimate customer transaction" over "stopping 100% of attacks automatically", which deployment model should they choose?', 'Deploy an IDS on a span port', 5, 'IDS cannot affect live traffic routing.', 0, ['Deploy an IPS in-line', 'Deploy an IDS on a span port', 'Deploy a stateless firewall', 'Disable all security controls']]
            ]
        }
    ]
};

async function seedNetworkSecurityPath() {
    try {
        console.log("🚀 Starting Network Security Path Seed Script...");

        // 1. Check if Path exists, if not create it
        let pathId;
        const existsRes = await runQuery(`SELECT id FROM learning_paths WHERE title = ?`, [netSecPath.title]);
        
        if (existsRes.rows.length > 0) {
            pathId = existsRes.rows[0].id;
            console.log(`ℹ️ Path already exists with ID: ${pathId}. Updating details...`);
            await runQuery(
                `UPDATE learning_paths SET description=?, difficulty_level=?, estimated_hours=?, display_order=? WHERE id=?`,
                [netSecPath.description, netSecPath.difficulty_level, netSecPath.estimated_hours, netSecPath.display_order, pathId]
            );
        } else {
            console.log("Creating new Learning Path...");
            const pathResult = await runQuery(
                `INSERT INTO learning_paths (title, description, difficulty_level, display_order, estimated_hours) VALUES (?, ?, ?, ?, ?)`, 
                [netSecPath.title, netSecPath.description, netSecPath.difficulty_level, netSecPath.display_order, netSecPath.estimated_hours]
            );
            pathId = pathResult.insertId || pathResult.rows[0].id;
            console.log(`✅ Path Created: ${netSecPath.title} (ID: ${pathId})`);
        }

        // 2. Create Module 1
        console.log(`\n📦 Creating Module: ${module1.title}`);
        let moduleId;
        const modExists = await runQuery(`SELECT id FROM modules WHERE learning_path_id=? AND title=?`, [pathId, module1.title]);
        
        if (modExists.rows.length > 0) {
            moduleId = modExists.rows[0].id;
            console.log(`   Module already exists (ID: ${moduleId}). Deleting old tasks to refresh...`);
            const tasks = await runQuery(`SELECT id FROM tasks WHERE module_id=?`, [moduleId]);
            for(let row of tasks.rows) {
                await runQuery(`DELETE FROM lesson_questions WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM lesson_content WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM tasks WHERE id=?`, [row.id]);
            }
        } else {
            const modResult = await runQuery(
                `INSERT INTO modules (learning_path_id, title, description, display_order) VALUES (?, ?, ?, ?)`,
                [pathId, module1.title, module1.description, module1.display_order]
            );
            moduleId = modResult.insertId || modResult.rows[0].id;
        }

        // 3. Create Tasks, Content, and Questions for Module 1
        for (const [taskIndex, taskData] of module1.tasks.entries()) {
            console.log(`   📝 Creating Task: ${taskData.title}`);
            const taskResult = await runQuery(
                `INSERT INTO tasks (module_id, title, xp_reward, display_order) VALUES (?, ?, ?, ?)`,
                [moduleId, taskData.title, taskData.xp_reward, taskIndex + 1]
            );
            const taskId = taskResult.insertId || taskResult.rows[0].id;

            await runQuery(
                `INSERT INTO lesson_content (task_id, content, content_type, reading_time_minutes) VALUES (?, ?, 'markdown', ?)`,
                [taskId, taskData.content, taskData.reading_time]
            );

            for (const q of taskData.questions) {
                const rawOptions = q[5];
                const shuffledOptions = rawOptions.sort(() => 0.5 - Math.random());
                const optionsJSON = JSON.stringify(shuffledOptions);
                await runQuery(
                    `INSERT INTO lesson_questions (task_id, question_text, correct_answer, question_order, hint, case_sensitive, options) VALUES (?, ?, ?, ?, ?, ?, ?)`,
                    [taskId, q[0], q[1], q[2], q[3], q[4], optionsJSON]
                );
            }
            console.log(`      ✓ Added content and ${taskData.questions.length} questions.`);
        }

        // 4. Create Module 2
        console.log(`\n📦 Creating Module: ${module2.title}`);
        let module2Id;
        const mod2Exists = await runQuery(`SELECT id FROM modules WHERE learning_path_id=? AND title=?`, [pathId, module2.title]);
        
        if (mod2Exists.rows.length > 0) {
            module2Id = mod2Exists.rows[0].id;
            console.log(`   Module already exists (ID: ${module2Id}). Deleting old tasks to refresh...`);
            const tasks2 = await runQuery(`SELECT id FROM tasks WHERE module_id=?`, [module2Id]);
            for(let row of tasks2.rows) {
                await runQuery(`DELETE FROM lesson_questions WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM lesson_content WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM tasks WHERE id=?`, [row.id]);
            }
        } else {
            const mod2Result = await runQuery(
                `INSERT INTO modules (learning_path_id, title, description, display_order) VALUES (?, ?, ?, ?)`,
                [pathId, module2.title, module2.description, module2.display_order]
            );
            module2Id = mod2Result.insertId || mod2Result.rows[0].id;
        }

        // 5. Create Tasks, Content, and Questions for Module 2
        for (const [taskIndex, taskData] of module2.tasks.entries()) {
            console.log(`   📝 Creating Task: ${taskData.title}`);
            const taskResult = await runQuery(
                `INSERT INTO tasks (module_id, title, xp_reward, display_order) VALUES (?, ?, ?, ?)`,
                [module2Id, taskData.title, taskData.xp_reward, taskIndex + 1]
            );
            const taskId = taskResult.insertId || taskResult.rows[0].id;

            await runQuery(
                `INSERT INTO lesson_content (task_id, content, content_type, reading_time_minutes) VALUES (?, ?, 'markdown', ?)`,
                [taskId, taskData.content, taskData.reading_time]
            );

            for (const q of taskData.questions) {
                const rawOptions = q[5];
                const shuffledOptions = rawOptions.sort(() => 0.5 - Math.random());
                const optionsJSON = JSON.stringify(shuffledOptions);
                await runQuery(
                    `INSERT INTO lesson_questions (task_id, question_text, correct_answer, question_order, hint, case_sensitive, options) VALUES (?, ?, ?, ?, ?, ?, ?)`,
                    [taskId, q[0], q[1], q[2], q[3], q[4], optionsJSON]
                );
            }
            console.log(`      ✓ Added content and ${taskData.questions.length} questions.`);
        }

        // 6. Create Module 3
        console.log(`\n📦 Creating Module: ${module3.title}`);
        let module3Id;
        const mod3Exists = await runQuery(`SELECT id FROM modules WHERE learning_path_id=? AND title=?`, [pathId, module3.title]);
        
        if (mod3Exists.rows.length > 0) {
            module3Id = mod3Exists.rows[0].id;
            console.log(`   Module already exists (ID: ${module3Id}). Deleting old tasks to refresh...`);
            const tasks3 = await runQuery(`SELECT id FROM tasks WHERE module_id=?`, [module3Id]);
            for(let row of tasks3.rows) {
                await runQuery(`DELETE FROM lesson_questions WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM lesson_content WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM tasks WHERE id=?`, [row.id]);
            }
        } else {
            const mod3Result = await runQuery(
                `INSERT INTO modules (learning_path_id, title, description, display_order) VALUES (?, ?, ?, ?)`,
                [pathId, module3.title, module3.description, module3.display_order]
            );
            module3Id = mod3Result.insertId || mod3Result.rows[0].id;
        }

        // 7. Create Tasks, Content, and Questions for Module 3
        for (const [taskIndex, taskData] of module3.tasks.entries()) {
            console.log(`   📝 Creating Task: ${taskData.title}`);
            const taskResult = await runQuery(
                `INSERT INTO tasks (module_id, title, xp_reward, display_order) VALUES (?, ?, ?, ?)`,
                [module3Id, taskData.title, taskData.xp_reward, taskIndex + 1]
            );
            const taskId = taskResult.insertId || taskResult.rows[0].id;

            await runQuery(
                `INSERT INTO lesson_content (task_id, content, content_type, reading_time_minutes) VALUES (?, ?, 'markdown', ?)`,
                [taskId, taskData.content, taskData.reading_time]
            );

            for (const q of taskData.questions) {
                const rawOptions = q[5];
                const shuffledOptions = rawOptions.sort(() => 0.5 - Math.random());
                const optionsJSON = JSON.stringify(shuffledOptions);
                await runQuery(
                    `INSERT INTO lesson_questions (task_id, question_text, correct_answer, question_order, hint, case_sensitive, options) VALUES (?, ?, ?, ?, ?, ?, ?)`,
                    [taskId, q[0], q[1], q[2], q[3], q[4], optionsJSON]
                );
            }
            console.log(`      ✓ Added content and ${taskData.questions.length} questions.`);
        }

        // 8. Create Module 4
        console.log(`\n📦 Creating Module: ${module4.title}`);
        let module4Id;
        const mod4Exists = await runQuery(`SELECT id FROM modules WHERE learning_path_id=? AND title=?`, [pathId, module4.title]);
        
        if (mod4Exists.rows.length > 0) {
            module4Id = mod4Exists.rows[0].id;
            console.log(`   Module already exists (ID: ${module4Id}). Deleting old tasks to refresh...`);
            const tasks4 = await runQuery(`SELECT id FROM tasks WHERE module_id=?`, [module4Id]);
            for(let row of tasks4.rows) {
                await runQuery(`DELETE FROM lesson_questions WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM lesson_content WHERE task_id=?`, [row.id]);
                await runQuery(`DELETE FROM tasks WHERE id=?`, [row.id]);
            }
        } else {
            const mod4Result = await runQuery(
                `INSERT INTO modules (learning_path_id, title, description, display_order) VALUES (?, ?, ?, ?)`,
                [pathId, module4.title, module4.description, module4.display_order]
            );
            module4Id = mod4Result.insertId || mod4Result.rows[0].id;
        }

        // 9. Create Tasks, Content, and Questions for Module 4
        for (const [taskIndex, taskData] of module4.tasks.entries()) {
            console.log(`   📝 Creating Task: ${taskData.title}`);
            const taskResult = await runQuery(
                `INSERT INTO tasks (module_id, title, xp_reward, display_order) VALUES (?, ?, ?, ?)`,
                [module4Id, taskData.title, taskData.xp_reward, taskIndex + 1]
            );
            const taskId = taskResult.insertId || taskResult.rows[0].id;

            await runQuery(
                `INSERT INTO lesson_content (task_id, content, content_type, reading_time_minutes) VALUES (?, ?, 'markdown', ?)`,
                [taskId, taskData.content, taskData.reading_time]
            );

            for (const q of taskData.questions) {
                const rawOptions = q[5];
                const shuffledOptions = rawOptions.sort(() => 0.5 - Math.random());
                const optionsJSON = JSON.stringify(shuffledOptions);
                await runQuery(
                    `INSERT INTO lesson_questions (task_id, question_text, correct_answer, question_order, hint, case_sensitive, options) VALUES (?, ?, ?, ?, ?, ?, ?)`,
                    [taskId, q[0], q[1], q[2], q[3], q[4], optionsJSON]
                );
            }
            console.log(`      ✓ Added content and ${taskData.questions.length} questions.`);
        }

        console.log("\n✅ Network Security Path - Modules 1, 2, 3, & 4 Seed Completed Successfully!");
        process.exit(0);

    } catch (error) {
        console.error("❌ Seed Failed:", error);
        process.exit(1);
    }
}

seedNetworkSecurityPath();
