"""Build the Windows handoff ZIP. Third-party binaries and release packages stay out of Git."""
import hashlib
import json
from pathlib import Path
import urllib.request
import zipfile

ROOT = Path(__file__).resolve().parent
URL = 'https://api.nuget.org/v3-flatcontainer/winscp/6.5.7/winscp.6.5.7.nupkg'
PACKAGE_SHA = 'f0923f848d83ee072570fb80b5899f0af678e9b5990220a6725a69781baf2aa2'


def build():
    runtime = ROOT / 'runtime'
    dist = ROOT / 'dist'
    runtime.mkdir(exist_ok=True)
    dist.mkdir(exist_ok=True)
    package = runtime / 'WinSCP.6.5.7.nupkg'
    if not package.exists():
        request = urllib.request.Request(URL, headers={'User-Agent': 'zhct220-bundle-builder'})
        with urllib.request.urlopen(request, timeout=120) as response:
            package.write_bytes(response.read())
    if hashlib.sha256(package.read_bytes()).hexdigest() != PACKAGE_SHA:
        raise SystemExit('WinSCP NuGet package SHA256 mismatch')
    with zipfile.ZipFile(package) as archive:
        (runtime / 'WinSCP.exe').write_bytes(archive.read('tools/WinSCP.exe'))
        (runtime / 'WinSCPnet.dll').write_bytes(archive.read('lib/net40/WinSCPnet.dll'))
        (runtime / 'upstream-README.md').write_bytes(archive.read('docs/README.md'))
        (runtime / 'WinSCP.nuspec').write_bytes(archive.read('WinSCP.nuspec'))
    hashes = {
        'Version': '6.5.7', 'SourceUrl': URL, 'NuGetSha256': PACKAGE_SHA,
        'ExeSha256': hashlib.sha256((runtime / 'WinSCP.exe').read_bytes()).hexdigest(),
        'DllSha256': hashlib.sha256((runtime / 'WinSCPnet.dll').read_bytes()).hexdigest(),
    }
    (ROOT / 'runtime-hashes.json').write_text(json.dumps(hashes, indent=2) + '\n', encoding='utf-8')
    bundle = dist / '张家港220一键升级.zip'
    top = '张家港220一键升级/'
    with zipfile.ZipFile(bundle, 'w', zipfile.ZIP_DEFLATED) as archive:
        for name in ['upgrade.ps1', 'config.json', 'remote-upgrade.sh', 'runtime-hashes.json', 'README.md', 'THIRD-PARTY.txt']:
            data = (ROOT / name).read_bytes()
            if name.endswith('.ps1'):
                data = b'\xef\xbb\xbf' + data.removeprefix(b'\xef\xbb\xbf')
            archive.writestr(top + '程序文件/' + name, data)
        for name in ['WinSCP.exe', 'WinSCPnet.dll', 'upstream-README.md', 'WinSCP.nuspec']:
            archive.write(runtime / name, top + '程序文件/runtime/' + name)
        launcher = (ROOT / '开始升级.cmd').read_text(encoding='utf-8')
        launcher = launcher.replace('cd /d "%~dp0"', 'cd /d "%~dp0程序文件"')
        launcher = launcher.replace('"%~dp0upgrade.ps1"', '"%~dp0程序文件\\upgrade.ps1"')
        archive.writestr(top + '开始升级.cmd', launcher.replace('\n', '\r\n').encode('utf-8'))
        archive.writestr(top + '先看我.txt',
            '解压整个文件夹后，双击“开始升级.cmd”。\r\n'
            '服务器密码、数据库密码各输入一次，输入时不显示，按回车即可。\r\n'
            '不要关闭正在运行的窗口。失败时把“程序文件\\logs”里的日志交给技术人员。\r\n'
            '首次现场使用需技术人员陪同验证；不需要手填配置或复制命令。\r\n'
            '密码不要填入配置文件，也不要发到群里。\r\n')
    digest = hashlib.sha256(bundle.read_bytes()).hexdigest()
    (dist / (bundle.name + '.sha256')).write_text(digest + '  ' + bundle.name + '\n', encoding='utf-8')
    print(json.dumps({'zip': str(bundle), 'size_bytes': bundle.stat().st_size, 'sha256': digest}, ensure_ascii=False))


if __name__ == '__main__':
    build()
