#!/usr/bin/env python3
#   BAREOS® - Backup Archiving REcovery Open Sourced
#
#   Copyright (C) 2026-2026 Bareos GmbH & Co. KG
#
#   This program is Free Software; you can redistribute it and/or
#   modify it under the terms of version three of the GNU Affero General Public
#   License as published by the Free Software Foundation and included
#   in the file LICENSE.
#
#   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
#   Affero General Public License for more details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
#   02110-1301, USA.
"""
embed_assets.py  <dist_dir>  <output_cc>

Walk <dist_dir>, gzip every file, and write a C++ source file that
defines the kEmbeddedFiles[] array used by the bareos-setup HTTP server.
"""
import os
import sys
import gzip
import mimetypes

MIME_MAP = {
    ".html": "text/html; charset=utf-8",
    ".js": "application/javascript",
    ".css": "text/css",
    ".svg": "image/svg+xml",
    ".ico": "image/x-icon",
    ".png": "image/png",
    ".woff": "font/woff",
    ".woff2": "font/woff2",
    ".json": "application/json",
    ".txt": "text/plain",
}


def mime_for(path):
    ext = os.path.splitext(path)[1].lower()
    return MIME_MAP.get(ext, "application/octet-stream")


def write_bytes(out, varname, data):
    out.write(f"static const uint8_t {varname}[] = {{\n")
    for i, b in enumerate(data):
        if i % 16 == 0:
            out.write("  ")
        out.write(f"0x{b:02x},")
        if (i + 1) % 16 == 0:
            out.write("\n")
    out.write("\n};\n")


def main():
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <dist_dir> <output.cc>", file=sys.stderr)
        sys.exit(1)

    dist_dir, out_path = sys.argv[1], sys.argv[2]

    # Collect files
    entries = []  # (url_path, varname, compressed_bytes, mime)
    for dirpath, _, filenames in os.walk(dist_dir):
        for fname in sorted(filenames):
            fpath = os.path.join(dirpath, fname)
            rel = os.path.relpath(fpath, dist_dir)
            url = "/" + rel.replace(os.sep, "/")
            varname = "_f" + str(len(entries))
            with open(fpath, "rb") as f:
                raw = f.read()
            compressed = gzip.compress(raw, compresslevel=9)
            entries.append((url, varname, compressed, mime_for(fname)))

    with open(out_path, "w") as out:
        out.write("// Auto-generated by embed_assets.py — do not edit\n")
        out.write('#include "embedded_assets.h"\n\n')

        for url, varname, data, mime in entries:
            out.write(f"// {url}  ({len(data)} bytes gzip)\n")
            write_bytes(out, varname, data)
            out.write("\n")

        out.write("const EmbeddedFile kEmbeddedFiles[] = {\n")
        for url, varname, data, mime in entries:
            safe_url = url.replace('"', '\\"')
            safe_mime = mime.replace('"', '\\"')
            out.write(
                f'  {{ "{safe_url}", {varname}, sizeof({varname}),'
                f' "{safe_mime}", true }},\n'
            )
        out.write("};\n\n")
        out.write(f"const size_t kEmbeddedFilesCount = {len(entries)};\n")

    print(f"Wrote {len(entries)} assets to {out_path}")


if __name__ == "__main__":
    main()
