#!/usr/bin/env python3
"""TextASite - publish a finished customer site to Cloudflare Pages.

THIS IS THE CANONICAL PUBLISH STEP. Customer sites do NOT go to Vercel.

Usage:
  publish_site.py <build-dir> [--phone +447...] [--project la-junk-removal] [--stage review]

  <build-dir>  folder of static files (must contain index.html)
  --phone      customer id in the tas-customers DynamoDB table; if given, the
               record is updated with site_url + stage (default stage: review)
  --project    cloudflare pages project name (default: slug of the customer's
               business name, else slug of the build dir)
  --stage      stage to set on the record (default review; use 'live' at go-live)
  --no-record  deploy only, don't touch DynamoDB

Result: https://<project>.pages.dev  (free, unlimited bandwidth, custom domains free)
"""
import argparse, json, os, re, subprocess, sys, urllib.request

HELPER = "/app/data/tas/deploy_site.sh"


def slugify(s):
    return re.sub(r"-+", "-", re.sub(r"[^a-z0-9]+", "-", (s or "").lower())).strip("-")[:40]


def get_customer(phone):
    import boto3
    t = boto3.resource("dynamodb", region_name="us-east-1").Table("tas-customers")
    return t.get_item(Key={"id": phone}).get("Item")


def update_customer(phone, url, stage):
    import boto3
    t = boto3.resource("dynamodb", region_name="us-east-1").Table("tas-customers")
    t.update_item(Key={"id": phone},
                  UpdateExpression="SET site_url=:u, stage=:s, host=:h",
                  ExpressionAttributeValues={":u": url, ":s": stage, ":h": "cloudflare-pages"})


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("build_dir")
    ap.add_argument("--phone")
    ap.add_argument("--project")
    ap.add_argument("--stage", default="review")
    ap.add_argument("--no-record", action="store_true")
    a = ap.parse_args()

    d = os.path.abspath(a.build_dir)
    if not os.path.isfile(os.path.join(d, "index.html")):
        sys.exit(f"no index.html in {d} - point this at the built static folder")

    cust = get_customer(a.phone) if (a.phone and not a.no_record) else None
    project = a.project or slugify((cust or {}).get("business") or os.path.basename(d.rstrip("/")))
    if not project:
        sys.exit("could not work out a project name - pass --project")

    print(f"publishing {d} -> https://{project}.pages.dev")
    r = subprocess.run([HELPER, project, d])
    if r.returncode != 0:
        sys.exit("deploy failed")

    url = f"https://{project}.pages.dev"

    # verify it is actually live before we claim anything
    code = 0
    try:
        with urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": "textasite"}), timeout=30) as resp:
            code = resp.status
    except Exception as e:
        print(f"verify failed: {e}")
    print(f"verify: {url} -> {code}")
    if code != 200:
        sys.exit("site is not returning 200 - not updating the customer record")

    if a.phone and not a.no_record:
        update_customer(a.phone, url, a.stage)
        print(f"record {a.phone}: site_url={url} stage={a.stage}")

    print(f"\nLIVE: {url}")


if __name__ == "__main__":
    main()
