#!/bin/bash

# Script to embed web assets into C code
#
# Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

echo "Embedding web assets..."

# Download pako libs if not present
mkdir -p templates/novnc/vendor/pako/lib/zlib
PAKO_FILES="adler32 constants crc32 deflate inflate inffast inftrees trees zstream"
for file in $PAKO_FILES; do
    if [ ! -f "templates/novnc/vendor/pako/lib/zlib/${file}.js" ]; then
        echo "Downloading pako ${file}.js..."
        curl -s -o "templates/novnc/vendor/pako/lib/zlib/${file}.js" "https://raw.githubusercontent.com/nodeca/pako/master/lib/zlib/${file}.js"
    fi
done

# Clean up old embedded files
rm -f image_data.h favicon_data.h

# Embed logo from logos directory (created by build.sh)
if [ -f ../logos/logo-128.png ]; then
    echo "Embedding logo-128.png..."
    xxd -i ../logos/logo-128.png > image_data.h
    # Rename the variables to match our expected names
    # xxd generates names like ___logos_logo_128_png, so we need to replace the entire variable names
    sed -i 's/unsigned char ___logos_logo_128_png\[\]/unsigned char image_jpg[]/g' image_data.h
    sed -i 's/unsigned int ___logos_logo_128_png_len/unsigned int image_jpg_len/g' image_data.h
elif [ -f ../image.jpg ]; then
    echo "Embedding image.jpg..."
    xxd -i ../image.jpg | sed 's/___image_jpg/image_jpg/g' > image_data.h
else
    echo "Warning: No image found, creating empty placeholder"
    cat > image_data.h << 'EOF'
unsigned char image_jpg[] = {};
unsigned int image_jpg_len = 0;
EOF
fi

# Embed favicon.ico
if [ -f ../logos/favicon.ico ]; then
    echo "Embedding favicon.ico..."
    xxd -i ../logos/favicon.ico > favicon_data.h
    # Rename the variables
    sed -i 's/unsigned char ___logos_favicon_ico\[\]/unsigned char favicon_ico[]/g' favicon_data.h
    sed -i 's/unsigned int ___logos_favicon_ico_len/unsigned int favicon_ico_len/g' favicon_data.h
else
    echo "Warning: favicon.ico not found, creating empty placeholder"
    cat > favicon_data.h << 'EOF'
unsigned char favicon_ico[] = {};
unsigned int favicon_ico_len = 0;
EOF
fi

# Embed xterm.js
if [ -f templates/xterm.js ]; then
    echo "Embedding xterm.js..."
    mkdir -p html_pages
    HEADER_FILE="html_pages/xterm_page.h"

    cat > "$HEADER_FILE" << EOF
/**
 * xterm.js library for wssshd
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef XTERM_PAGE_H
#define XTERM_PAGE_H

// xterm.js library
const char *xterm_js =
EOF

    # Process the JS file, escape quotes and backslashes
    sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' templates/xterm.js >> "$HEADER_FILE"

    # Close the string and header
    cat >> "$HEADER_FILE" << EOF
;

#endif /* XTERM_PAGE_H */
EOF
else
    echo "Warning: xterm.js not found, creating empty placeholder"
    mkdir -p html_pages
    cat > html_pages/xterm_page.h << 'EOF'
#ifndef XTERM_PAGE_H
#define XTERM_PAGE_H
static const char *xterm_js = "";
#endif /* XTERM_PAGE_H */
EOF
fi

# Embed xterm-addon-fit.js
if [ -f templates/xterm-addon-fit.js ]; then
    echo "Embedding xterm-addon-fit.js..."
    mkdir -p html_pages
    HEADER_FILE="html_pages/xterm_addon_page.h"

    cat > "$HEADER_FILE" << EOF
/**
 * xterm-addon-fit.js library for wssshd
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef XTERM_ADDON_PAGE_H
#define XTERM_ADDON_PAGE_H

// xterm-addon-fit.js library
const char *xterm_addon_fit_js =
EOF

    # Process the JS file, escape quotes and backslashes
    sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' templates/xterm-addon-fit.js >> "$HEADER_FILE"

    # Close the string and header
    cat >> "$HEADER_FILE" << EOF
;

#endif /* XTERM_ADDON_PAGE_H */
EOF
else
    echo "Warning: xterm-addon-fit.js not found, creating empty placeholder"
    mkdir -p html_pages
    cat > html_pages/xterm_addon_page.h << 'EOF'
#ifndef XTERM_ADDON_PAGE_H
#define XTERM_ADDON_PAGE_H
static const char *xterm_addon_fit_js = "";
#endif /* XTERM_ADDON_PAGE_H */
EOF
fi

# Embed mstsc.js
if [ -f templates/mstsc.min.js ]; then
    echo "Embedding mstsc.min.js..."
    mkdir -p html_pages
    HEADER_FILE="html_pages/mstsc_page.h"

    cat > "$HEADER_FILE" << EOF
/**
 * mstsc.js library for wssshd
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef MSTSC_PAGE_H
#define MSTSC_PAGE_H

// mstsc.js library
const char *mstsc_js =
EOF

    # Process the JS file, escape quotes and backslashes
    sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' templates/mstsc.min.js >> "$HEADER_FILE"

    # Close the string and header
    cat >> "$HEADER_FILE" << EOF
;

#endif /* MSTSC_PAGE_H */
EOF
else
    echo "Warning: mstsc.min.js not found, creating empty placeholder"
    mkdir -p html_pages
    cat > html_pages/mstsc_page.h << 'EOF'
#ifndef MSTSC_PAGE_H
#define MSTSC_PAGE_H
static const char *mstsc_js = "";
#endif /* MSTSC_PAGE_H */
EOF
fi

# Embed RDP JS files
echo "Embedding RDP JS files..."
mkdir -p html_pages

# Generate rdp_assets.h
cat > rdp_assets.h << 'EOF'
#ifndef RDP_ASSETS_H
#define RDP_ASSETS_H
EOF

# Generate rdp_asset_map.c
cat > rdp_asset_map.c << 'EOF'
#include <string.h>
#include "rdp_assets.h"

const char *get_rdp_asset(const char *path, size_t *size) {
EOF


find templates/rdpwasm -name "*.js" | sort | while read -r file; do
    if [ -f "$file" ]; then
        RELPATH=$(echo "$file" | sed 's|templates/rdpwasm/||')
        VARNAME=$(echo "$RELPATH" | sed 's|/|_|g; s|\.js$|_js|; s|\.|_|g')
        HEADER_FILE="html_pages/rdp_${VARNAME}_page.h"

        echo "Embedding $file as rdp_${VARNAME}"

        # Create header with extern
        cat > "$HEADER_FILE" << EOF
#ifndef RDP_${VARNAME^^}_PAGE_H
#define RDP_${VARNAME^^}_PAGE_H

extern const char *rdp_${VARNAME};

#endif /* RDP_${VARNAME^^}_PAGE_H */
EOF

        # Add to rdp_assets.h
        echo "#include \"html_pages/rdp_${VARNAME}_page.h\"" >> rdp_assets.h

        # Add definition to rdp_asset_map.c
        echo "const char *rdp_${VARNAME} =" >> rdp_asset_map.c
        # Use python to properly escape
        python3 -c "
import sys
with open('$file', 'r', encoding='utf-8', errors='ignore') as f:
    content = f.read()
lines = content.split('\n')
for line in lines:
    escaped_line = line.replace('\\\\', '\\\\\\\\').replace('\\\"', '\\\\\"')
    print('\"' + escaped_line + '\\\\n\"')
" >> rdp_asset_map.c
        echo ";" >> rdp_asset_map.c

        # Add to rdp_asset_map.c
        echo "    if (strcmp(path, \"/rdpwasm/$RELPATH\") == 0) {" >> rdp_asset_map.c
        echo "        if (size) *size = strlen(rdp_${VARNAME});" >> rdp_asset_map.c
        echo "        return rdp_${VARNAME};" >> rdp_asset_map.c
        echo "    }" >> rdp_asset_map.c
    fi
done

find templates/rdpwasm -name "*.wasm" | sort | while read -r file; do
    if [ -f "$file" ]; then
        RELPATH=$(echo "$file" | sed 's|templates/rdpwasm/||')
        VARNAME=$(echo "$RELPATH" | sed 's|/|_|g; s|\.wasm$|_wasm|; s|\.|_|g')
        HEADER_FILE="html_pages/rdp_${VARNAME}_page.h"

        echo "Embedding $file as rdp_${VARNAME}"

        # Create header with extern
        cat > "$HEADER_FILE" << EOF
#ifndef RDP_${VARNAME^^}_PAGE_H
#define RDP_${VARNAME^^}_PAGE_H

extern const unsigned char rdp_${VARNAME}[];
extern const unsigned int rdp_${VARNAME}_len;

#endif /* RDP_${VARNAME^^}_PAGE_H */
EOF

        # Add to rdp_assets.h
        echo "#include \"html_pages/rdp_${VARNAME}_page.h\"" >> rdp_assets.h

        # Embed binary file
        xxd -i "$file" > temp_binary.h
        # Rename the variables and add static
        sed -i "s/templates_rdpwasm_rdp_wasm/rdp_rdp_wasm/g" temp_binary.h
        sed -i "s/unsigned char rdp_rdp_wasm\[\]/static unsigned char rdp_rdp_wasm[]/g" temp_binary.h
        sed -i "s/unsigned int rdp_rdp_wasm_len/static unsigned int rdp_rdp_wasm_len/g" temp_binary.h
        cat temp_binary.h >> rdp_asset_map.c
        rm temp_binary.h

        # Add to rdp_asset_map.c
        echo "    if (strcmp(path, \"/rdpwasm/$RELPATH\") == 0) {" >> rdp_asset_map.c
        echo "        if (size) *size = rdp_${VARNAME}_len;" >> rdp_asset_map.c
        echo "        return (const char *)rdp_${VARNAME};" >> rdp_asset_map.c
        echo "    }" >> rdp_asset_map.c
    fi
done

cat >> rdp_assets.h << 'EOF'
#endif /* RDP_ASSETS_H */
EOF

cat >> rdp_asset_map.c << 'EOF'
    return NULL;
}
EOF

echo "RDP JS files embedded."

# Embed noVNC CSS
if [ -f templates/novnc.css ]; then
    echo "Embedding novnc.css..."
    mkdir -p html_pages
    HEADER_FILE="html_pages/novnc_css_page.h"

    cat > "$HEADER_FILE" << EOF
/**
 * noVNC CSS for wssshd
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef NOVNC_CSS_PAGE_H
#define NOVNC_CSS_PAGE_H

// noVNC CSS
const char *novnc_css =
EOF

    # Process the CSS file, escape quotes and backslashes
    sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' templates/novnc.css >> "$HEADER_FILE"

    # Close the string and header
    cat >> "$HEADER_FILE" << EOF
;

#endif /* NOVNC_CSS_PAGE_H */
EOF
else
    echo "Warning: novnc.css not found, creating empty placeholder"
    mkdir -p html_pages
    cat > html_pages/novnc_css_page.h << 'EOF'
#ifndef NOVNC_CSS_PAGE_H
#define NOVNC_CSS_PAGE_H
static const char *novnc_css = "";
#endif /* NOVNC_CSS_PAGE_H */
EOF
fi

# Embed all noVNC JS files
echo "Embedding noVNC JS files..."
mkdir -p html_pages

# Generate novnc_assets.h
cat > novnc_assets.h << 'EOF'
#ifndef NOVNC_ASSETS_H
#define NOVNC_ASSETS_H
EOF

# Generate novnc_asset_map.c
cat > novnc_asset_map.c << 'EOF'
#include <string.h>
#include "novnc_assets.h"

const char *get_novnc_asset(const char *path) {
EOF

find templates/novnc templates/vendor -name "*.js" | sort | while read -r jsfile; do
    if [ -f "$jsfile" ]; then
        RELPATH=$(echo "$jsfile" | sed 's|templates/novnc/||')
        RELDIR=$(dirname "$RELPATH")
        if [ "$RELDIR" = "." ]; then
            RELDIR=""
        else
            RELDIR="$RELDIR/"
        fi
        VARNAME=$(echo "$RELPATH" | sed 's|/|_|g; s|\.js$|_js|')
        HEADER_FILE="html_pages/novnc_${VARNAME}_page.h"

        echo "Embedding $jsfile as novnc_${VARNAME}"

        # Create header with extern
        cat > "$HEADER_FILE" << EOF
#ifndef NOVNC_${VARNAME^^}_PAGE_H
#define NOVNC_${VARNAME^^}_PAGE_H

extern const char *novnc_${VARNAME};

#endif /* NOVNC_${VARNAME^^}_PAGE_H */
EOF

        # Add to novnc_assets.h
        echo "#include \"html_pages/novnc_${VARNAME}_page.h\"" >> novnc_assets.h

        # Add definition to novnc_asset_map.c
        echo "const char *novnc_${VARNAME} =" >> novnc_asset_map.c
        CONTENT=$(sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' "$jsfile")
        if echo "$jsfile" | grep -q "vendor/pako"; then
            # Convert CommonJS to ES6 for pako files
            CONTENT=$(echo "$CONTENT" | sed "s|\"const \([a-zA-Z_][a-zA-Z0-9_]*\) = require('\./\([^']*\)');\"|\"import \1 from './\2.js';\"|g")
            CONTENT=$(echo "$CONTENT" | sed "s|\"const { \([^}]*\) } = require('\./constants');\"|\"import * as constants from './constants.js'; const { \1 } = constants;\"|g")
            CONTENT=$(echo "$CONTENT" | sed "s|\"const { \([^}]*\) } = require('\./\([^']*\)');\"|\"import { \1 } from './\2.js';\"|g")
            CONTENT=$(echo "$CONTENT" | sed "s|\"module\.exports\.\([a-zA-Z_][a-zA-Z0-9_]*\)[[:space:]]*\=[[:space:]]*\([a-zA-Z_][a-zA-Z0-9_]*\);\"|\"export { \1 };\"|g")
            CONTENT=$(echo "$CONTENT" | sed "s|\"module\.exports[[:space:]]*=[[:space:]]*\([a-zA-Z_][a-zA-Z0-9_]*\);\"|\"export default \1;\"|g")
            # Special for constants.js
            CONTENT=$(echo "$CONTENT" | sed 's|\"module.exports = {|\"export default {|g')
            # Special for deflate.js to export constants
            # if echo "$jsfile" | grep -q "deflate.js"; then
            #     CONTENT=$(echo "$CONTENT" | sed '$a "export { Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_FULL_FLUSH, Z_FINISH, Z_BLOCK, Z_OK, Z_STREAM_END, Z_STREAM_ERROR, Z_DATA_ERROR, Z_BUF_ERROR, Z_DEFAULT_COMPRESSION, Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE, Z_FIXED, Z_DEFAULT_STRATEGY, Z_UNKNOWN, Z_DEFLATED };"')
            # fi
            # Special for zstream.js
            if echo "$jsfile" | grep -q "zstream.js"; then
                CONTENT=$(echo "$CONTENT" | sed 's|\"export { ZStream };\"|\"export default ZStream;\"|g')
            fi
        fi
        echo "$CONTENT" | sed "s|'\\./|'/novnc/$RELDIR|g; s|\"\\./|\"/novnc/$RELDIR|g" | sed "s|'\\.\./vendor/|'/novnc/vendor/|g; s|\"\\.\./vendor/|\"/novnc/vendor/|g" >> novnc_asset_map.c
        echo ";" >> novnc_asset_map.c

        # Add to novnc_asset_map.c
        echo "    if (strcmp(path, \"/novnc/$RELPATH\") == 0) return novnc_${VARNAME};" >> novnc_asset_map.c
    fi
done

cat >> novnc_assets.h << 'EOF'
#endif /* NOVNC_ASSETS_H */
EOF

cat >> novnc_asset_map.c << 'EOF'
    return NULL;
}
EOF

echo "noVNC JS files embedded."

# Check if we need to process an HTML template
if [ $# -eq 1 ] && [[ "$1" == *.html ]]; then
    echo "Processing HTML template: $1"
    BASENAME=$(basename "$1" .html)
    HEADER_FILE="html_pages/${BASENAME}_page.h"
    mkdir -p html_pages

    # Generate C header with HTML content
    cat > "$HEADER_FILE" << EOF
/**
* ${BASENAME} page HTML template for wssshd
*
* Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef ${BASENAME^^}_PAGE_H
#define ${BASENAME^^}_PAGE_H

// ${BASENAME} page HTML template
EOF

    # Add __attribute__((used)) for vnc_page_html to suppress unused variable warning
    if [ "$BASENAME" = "vnc" ]; then
        echo "static const char *${BASENAME}_page_html __attribute__((used)) =" >> "$HEADER_FILE"
    else
        echo "static const char *${BASENAME}_page_html =" >> "$HEADER_FILE"
    fi

    # Process the HTML file, escape quotes and replace {{ variables }} with %s
    sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' "$1" | \
    sed 's/{{[^}]*}}/%s/g' >> "$HEADER_FILE"

    # Close the string and header
    cat >> "$HEADER_FILE" << EOF
;

#endif /* ${BASENAME^^}_PAGE_H */
EOF

    echo "HTML template processed: $HEADER_FILE"
fi

# Process all HTML templates in templates/ directory
for template in templates/*.html; do
    if [ -f "$template" ]; then
        BASENAME=$(basename "$template" .html)
        echo "Processing HTML template: $template"
        HEADER_FILE="html_pages/${BASENAME}_page.h"
        mkdir -p html_pages

        # Generate C header with HTML content
        # Add __attribute__((used)) for vnc_page_html to suppress unused variable warning
        if [ "$BASENAME" = "vnc" ]; then
            cat > "$HEADER_FILE" << EOF
/**
 * ${BASENAME} page HTML template for wssshd
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef ${BASENAME^^}_PAGE_H
#define ${BASENAME^^}_PAGE_H

// ${BASENAME} page HTML template
static const char *${BASENAME}_page_html __attribute__((used)) =
EOF
        else
            cat > "$HEADER_FILE" << EOF
/**
 * ${BASENAME} page HTML template for wssshd
 *
 * Copyright (C) 2024 Stefy Lanza <stefy@nexlab.net> and SexHack.me
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef ${BASENAME^^}_PAGE_H
#define ${BASENAME^^}_PAGE_H

// ${BASENAME} page HTML template
static const char *${BASENAME}_page_html =
EOF
        fi

        # Process the HTML file, escape quotes and backslashes
        sed 's/\\/\\\\/g; s/"/\\"/g; s/^/"/; s/$/\\n"/' "$template" >> "$HEADER_FILE"

        # Close the string and header
        cat >> "$HEADER_FILE" << EOF
;

#endif /* ${BASENAME^^}_PAGE_H */
EOF

        echo "HTML template processed: $HEADER_FILE"
    fi
done

echo "Assets embedded successfully"