#!/usr/bin/env python3
"""
Build the release package nagimanga-vX.Y.Z.zip (standard library only).

    python dev/build_release.py          -> dev/results/nagimanga-vX.Y.Z.zip and .zip.sig

Layout (the admin's self-update reads exactly this):
    nagimanga/...              the contents of server/ (data/ and plugins/ only with their guard files)
    optional/guest-mode.php    the guest mode plugin
    README.txt                 first steps

Attach the ZIP and its .sig to a GitHub release of Lichiphen/NagiSwipe. Installed copies find
them through the releases API, check the ZIP against the SHA-256 GitHub shows for the asset,
and (from 0.12.0 on) against the signature made here with the key from dev/release_sign.py.
"""
import hashlib
import re
import subprocess
import sys
import zipfile
from pathlib import Path

import release_sign

HERE = Path(__file__).resolve().parent
MANGA = HERE.parent
SERVER = MANGA / "server"

README = """NagiManga v{version}

はじめて設置するとき
1. nagimanga フォルダの中身を、FTP でサーバーの好きな場所にアップロードします。
   .htaccess（. で始まるファイル）も必ず送ってください。
2. ブラウザで https://あなたのサイト/nagimanga/admin/ を開きます。
   FTP で data/setup-key.php を開き、書いてある「セットアップの鍵」を貼り付けて、パスワードを決めます。
3. 表示されたログイン URL をブックマークします。
4. ログインして、作品一覧に「data フォルダがインターネットから見える状態です」が出ていないことを確認します。
5. 設定の「公開URL」に設置先を入れます。log.php は付けません。

個人用LOG（NagiLog）
・公開サイトは https://あなたのサイト/nagimanga/ です。
・「LOG・投稿」で、文章、画像、漫画、動画、音声、カテゴリ、ハッシュタグを投稿できます。
・既定パスワードはありません。初回に自分で設定します。
・メリット・デメリットと設置の注意点は、同梱の README-LOG.md にまとめています。
・.htaccess が使えない環境では、data を公開フォルダの外へ移すか、サーバー側でアクセスを拒否してください。

更新するとき
・v0.2.0 以降は、管理画面の「更新」から更新できます（新しいバージョンが出るとログイン時にお知らせします）。
・手動で更新する場合は、nagimanga フォルダの中身を上書きアップロードします。
  data フォルダはアップロードしないでください（作品と設定が消えます）。
・更新したら、管理画面の「設置用コード」でキャッシュバスター（?v= の値）を確認して貼り直してください。

optional/guest-mode.php は、デモなどで管理画面を閲覧のみで見せたいときだけ nagimanga/plugins/ に置きます。

詳しい説明: https://github.com/Lichiphen/NagiSwipe/blob/main/manga/README.md
デモ: https://notebook.lichiphen.com/nagimanga/demo.html

----------------------------------------------------------------
English

First installation
1. Upload the contents of the nagimanga folder to any place on your server with FTP.
   Send the .htaccess files (files starting with .) too.
2. Open https://your-site/nagimanga/admin/ in a browser. Open data/setup-key.php with FTP,
   paste the "setup key" written in it, and choose your password.
3. Bookmark the login URL that is shown.
4. Log in and check that the work list does not warn that the data folder can be seen from the internet.
5. Enter where it is installed as the "Public URL" in the settings (without log.php).
The admin panel can be shown in English: Settings > Common and security > Admin panel language.

Personal log (NagiLog)
- The public site is https://your-site/nagimanga/
- "Log and posts" posts text, pictures, manga, video, audio, categories and hashtags.
- There is no default password. You set it the first time.
- Strengths, weaknesses and cautions for installing are in README-LOG.en.md (included).

Updating
- From v0.2.0 on, update from "Update" in the admin panel (a notice appears at login when a new version is out).
- To update by hand, upload the contents of the nagimanga folder over the old files.
  Do not upload the data folder (your works and settings would be lost).

Documentation: https://nagiswipe.pages.dev/index.en.html
MIT License (c) 2026 Lichiphen
"""


def main():
    boot = (SERVER / "lib" / "bootstrap.php").read_text(encoding="utf-8")
    viewer = (SERVER / "viewer" / "NagiManga.js").read_text(encoding="utf-8")
    version = re.search(r"const NM_VERSION = '([0-9]+\.[0-9]+\.[0-9]+)';", boot).group(1)
    vv = re.search(r"const VERSION = '([0-9.]+)';", viewer).group(1)
    if vv != version:
        sys.exit(f"version mismatch: lib/bootstrap.php {version} / viewer/NagiManga.js {vv}")
    # Badges in the READMEs and on the site must show this version (the post-commit hook skips them when a README is dirty).
    if subprocess.run([sys.executable, str(MANGA.parent / "scripts" / "check_versions.py")]).returncode != 0:
        sys.exit("version badges: run python scripts/check_versions.py --fix and commit first")
    # The customizing catalog must match the stylesheets, and its "next" entries must carry this version.
    if subprocess.run([sys.executable, str(HERE / "css_catalog_check.py"), "--release"]).returncode != 0:
        sys.exit("css-catalog.json: fix the problems above first")

    out = HERE / "results" / f"nagimanga-v{version}.zip"
    out.parent.mkdir(exist_ok=True)
    with zipfile.ZipFile(out, "w", zipfile.ZIP_DEFLATED) as z:
        for f in sorted(SERVER.rglob("*")):
            rel = f.relative_to(SERVER).as_posix()
            # viewer/NagiSwipe-main.* may be local working copies of the root files; the root ones are bundled below
            if not f.is_file() or rel in ("lib/paths.php", "viewer/NagiSwipe-main.js", "viewer/NagiSwipe-main.css") or f.suffix in (".tmp", ".bak"):
                continue
            top = rel.split("/", 1)[0]
            if top in ("data", "plugins") and rel not in (f"{top}/.htaccess", f"{top}/index.html"):
                continue
            z.write(f, "nagimanga/" + rel)
        # Bundle the root gallery without keeping a second source copy in Git.
        for name in ("NagiSwipe-main.js", "NagiSwipe-main.css"):
            z.write(MANGA.parent / name, "nagimanga/viewer/" + name)
        z.write(MANGA / "plugins" / "guest-mode.php", "optional/guest-mode.php")
        for name in ("README.md", "README.en.md", "README-LOG.md", "README-LOG.en.md"):
            z.write(MANGA / name, name)
        for doc in sorted((MANGA / "docs").glob("*.md")):
            z.write(doc, "docs/" + doc.name)
        z.writestr("README.txt", ("﻿" + README.format(version=version)).replace("\n", "\r\n").encode("utf-8"))
    digest = hashlib.sha256(out.read_bytes()).hexdigest()
    print(f"{out}\nsha256:{digest}")
    # Installed sites refuse an update without it; --unsigned is only for local packages that are never published.
    if "--unsigned" in sys.argv:
        print("(not signed)")
        return
    sig = release_sign.sign_release(out, version)
    print(f"{sig}  <- attach to the release together with the ZIP")


if __name__ == "__main__":
    main()
