#!/usr/bin/env python3
"""AppWanderer CLI - a tiny, dependency-free client for the AppWanderer Data API.

Docs & keys: https://appwanderer.com/developers
Set your key first:  export APPWANDERER_API_KEY=YOUR_KEY

Usage:  appwanderer <command> [args] [--limit N] [--page N]

Commands:
  records                 list all record boards
  record <slug>           one board with its entries   (e.g. record biggest-app)
  apps                    tracked apps by rating count
  app <id>                one app's metrics            (e.g. app 284882215)
  publishers              publisher directory
  developer <artist_id>   one publisher: dossier + apps
  categories              all categories
  category <slug>         one category report
  studies                 all data studies
  study <slug>            one study's figures          (e.g. study app-store-pricing)
  almanac [<week>]        almanac editions, or one edition
  movers                  7-day board climbers
  search <query>          find apps by name
  raw <path>              call an arbitrary /api/v1 path
"""
import os, sys, json, urllib.request, urllib.parse, urllib.error

BASE = "https://appwanderer.com/api/v1"

def call(path, params=None):
    key = os.environ.get("APPWANDERER_API_KEY", "")
    if not key:
        sys.exit("error: set APPWANDERER_API_KEY (get an approved key at https://appwanderer.com/developers).")
    url = BASE + path
    if params:
        url += "?" + urllib.parse.urlencode({k: v for k, v in params.items() if v is not None})
    req = urllib.request.Request(url, headers={"Authorization": "Bearer " + key, "Accept": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=30) as r:
            return json.load(r)
    except urllib.error.HTTPError as e:
        try:
            msg = json.load(e)
        except Exception:
            msg = {"error": "http_error", "status": e.code}
        sys.exit("HTTP %d: %s" % (e.code, json.dumps(msg)))
    except urllib.error.URLError as e:
        sys.exit("network error: %s" % e.reason)

def main(argv):
    if not argv or argv[0] in ("-h", "--help", "help"):
        print(__doc__)
        return 0
    def opt(name):
        return argv[argv.index(name) + 1] if name in argv and argv.index(name) + 1 < len(argv) else None
    cmd = argv[0]
    rest = [a for a in argv[1:] if not a.startswith("--")]
    q = {"limit": opt("--limit"), "page": opt("--page")}
    arg = rest[0] if rest else ""
    routes = {
        "records": ("/records", q),
        "record": ("/record/" + arg, {"limit": q["limit"]}),
        "apps": ("/apps", q),
        "app": ("/app/" + arg, None),
        "publishers": ("/publishers", q),
        "developer": ("/developer/" + arg, q),
        "categories": ("/categories", None),
        "category": ("/category/" + arg, None),
        "studies": ("/studies", None),
        "study": ("/studies/" + arg, None),
        "almanac": ("/almanac/" + arg if arg else "/almanac", None),
        "movers": ("/movers", {"limit": q["limit"]}),
        "search": ("/search", {"q": arg}),
        "raw": (arg or "/", q),
    }
    if cmd not in routes:
        sys.exit("unknown command: %s (run with --help)" % cmd)
    path, params = routes[cmd]
    print(json.dumps(call(path, params), indent=2, ensure_ascii=False))
    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))