#!/usr/bin/env python3
"""Minimal ar archive packer/extractor for .deb files on a-Shell.

Usage:
  ardeb pack <out.ar> <file> [file ...]
  ardeb extract <in.ar> <dest-dir>
"""

import os
import sys


def pack(out_path, files):
    with open(out_path, "wb") as out:
        out.write(b"!<arch>\n")
        for path in files:
            data = open(path, "rb").read()
            name = os.path.basename(path)
            if len(name) > 15:
                raise SystemExit("ardeb: member name too long: " + name)
            header = (
                name.ljust(16)
                + "0".ljust(12)
                + "0".ljust(6)
                + "0".ljust(6)
                + "100644".ljust(8)
                + str(len(data)).ljust(10)
                + "`\n"
            ).encode("ascii")
            out.write(header)
            out.write(data)
            if len(data) & 1:
                out.write(b"\n")


def extract(archive, dest):
    data = open(archive, "rb").read()
    if not data.startswith(b"!<arch>\n"):
        raise SystemExit("ardeb: not an ar archive")
    os.makedirs(dest, exist_ok=True)
    pos = 8
    while pos + 60 <= len(data):
        header = data[pos:pos + 60]
        pos += 60
        name = header[:16].decode("ascii", "ignore").strip().rstrip("/")
        if not name:
            continue
        try:
            size = int(header[48:58].decode("ascii", "ignore").strip() or "0")
        except ValueError:
            size = 0
        body = data[pos:pos + size]
        pos += size + (size & 1)
        if name in (".", ".."):
            continue
        open(os.path.join(dest, name), "wb").write(body)


def main():
    if len(sys.argv) < 4:
        raise SystemExit(__doc__)
    if sys.argv[1] == "pack":
        pack(sys.argv[2], sys.argv[3:])
    elif sys.argv[1] == "extract":
        extract(sys.argv[2], sys.argv[3])
    else:
        raise SystemExit(__doc__)


if __name__ == "__main__":
    main()
