#!/usr/bin/env python3
"""
Build a deploy bundle on the Mac.

There is no SSH from the Mac to the server, so a deploy is: build one file
here, upload it, run it there. The file is always called ship.py. It is not
named after whatever is being fixed, because a script named after a symptom
is a script nobody can reuse, and this estate accumulated a pile of them.

  MAC:
    cd "Plugins/The Panel"
    python3 deploy/build_ship.py mostafaei templates/cms/dashboard.html
    python3 deploy/build_ship.py finaltarget apps/contact/views.py apps/contact/antispam.py

  Then upload deploy/out/ship.py to /home/<user>/ and:

  SERVER:
    python3 /home/<user>/ship.py            shows a diff, changes nothing
    python3 /home/<user>/ship.py --apply    backs up, writes, restarts, verifies

Paths are given relative to the install root, the folder holding apps/ and
templates/. Files are read from this tree unless --from is given.
"""

import argparse
import base64
import hashlib
import json
import os
import sys

HERE = os.path.dirname(os.path.abspath(__file__))
TREE = os.path.dirname(HERE)

SITES = {
    'finaltarget': {
        'user': 'finaltarget',
        'base': '/home/finaltarget/public_html/backend',
        'service': 'finaltarget',
        'health': 'https://finaltarget.com/',
        'panel': 'https://panel.finaltarget.com/auth/login/',
        'marker': 'finaltarget',
    },
    'mostafaei': {
        'user': 'mostafaei',
        'base': '/home/mostafaei/public_html/backend',
        'service': 'mostafaei',
        'health': 'https://mostafaei.com/',
        'panel': 'https://panel.mostafaei.com/auth/login/',
        'marker': 'mostafaei',
    },
    'hpglobal': {
        'user': 'hpglobal',
        'base': '/home/hpglobal/public_html/backend',
        'service': 'hpglobal',
        'health': 'https://hpglobal.uk/',
        'panel': 'https://panel.hpglobal.uk/auth/login/',
        'marker': 'hpglobal',
    },
    'paneltest': {
        'user': 'paneltest',
        'base': '/home/paneltest/public_html/backend',
        'service': 'paneltest',
        'health': 'https://paneltest.finaltarget.com/',
        'panel': 'https://paneltest.finaltarget.com/auth/login/',
        'marker': 'paneltest',
    },
}


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('site', choices=sorted(SITES))
    ap.add_argument('paths', nargs='+', help='paths relative to the install root')
    ap.add_argument('--from', dest='src', default=TREE,
                    help='tree to read the files from, defaults to The Panel')
    ap.add_argument('--out', default=os.path.join(HERE, 'out', 'ship.py'))
    args = ap.parse_args()

    site = SITES[args.site]
    payload = {}
    for rel in args.paths:
        full = os.path.join(args.src, rel)
        if not os.path.isfile(full):
            sys.exit('not in the tree: %s' % full)
        data = open(full, 'rb').read()
        payload[rel] = {
            'b64': base64.b64encode(data).decode(),
            'sha': hashlib.sha256(data).hexdigest(),
            'size': len(data),
        }
        print('  %-52s %6d bytes  %s' % (rel, len(data), payload[rel]['sha'][:12]))

    runner = open(os.path.join(HERE, 'ship_runner.py')).read()
    out = runner.replace('__SITE__', json.dumps(site, indent=4))
    out = out.replace('__FILES__', json.dumps(payload, indent=4))
    out = out.replace('__SOURCE__', json.dumps(os.path.basename(args.src)))

    os.makedirs(os.path.dirname(args.out), exist_ok=True)
    open(args.out, 'w').write(out)
    print()
    print('  bundle : %s' % args.out)
    print('  target : %s on %s' % (site['base'], args.site))
    print('  upload it to /home/%s/ and run it there' % site['user'])


if __name__ == '__main__':
    main()
