#!/usr/bin/env python3
"""Check a .mobi/.azw/.azw3 file before uploading it for translation.

Reads only the file headers (Python standard library, no dependencies).
Usage: python3 inspect_kindle_file.py book.mobi [more files...]
"""
import struct, sys

COMPRESSION = {1: "none", 2: "PalmDOC", 17480: "HUFF/CDIC"}
ENCRYPTION = {0: "none", 1: "old Mobipocket DRM", 2: "Mobipocket DRM"}
ENCODING = {1252: "Windows-1252", 65001: "UTF-8"}

def exth(rec0, mobi_len):
    out = {}
    start = 16 + mobi_len
    if rec0[start:start + 4] != b"EXTH":
        return out
    count = struct.unpack(">I", rec0[start + 8:start + 12])[0]
    pos = start + 12
    for _ in range(count):
        tag, size = struct.unpack(">II", rec0[pos:pos + 8])
        out.setdefault(tag, rec0[pos + 8:pos + size])
        pos += size
    return out

def inspect(path):
    data = open(path, "rb").read()
    if data[:4] == b"PK\x03\x04":
        return "ZIP container (EPUB or KFX-ZIP), not a MOBI-family file"
    if data[:7] == b"\xeaDRMION":
        return "KFX with DRM: cannot be translated; use a DRM-free source"
    if data[:3] == b"TPZ":
        return "Topaz book: not a MOBI file; use a DRM-free source"
    if data[60:68] not in (b"BOOKMOBI", b"TEXtREAd"):
        return f"not a MOBI-family file (type/creator {data[60:68]!r})"
    nrec = struct.unpack(">H", data[76:78])[0]
    offs = [struct.unpack(">I", data[78 + 8 * i:82 + 8 * i])[0] for i in range(nrec)]
    rec0 = data[offs[0]:offs[1]]
    comp = struct.unpack(">H", rec0[0:2])[0]
    enc = struct.unpack(">H", rec0[12:14])[0]
    lines = [f"compression: {COMPRESSION.get(comp, comp)}",
             f"encryption: {ENCRYPTION.get(enc, enc)}"]
    if rec0[16:20] == b"MOBI":
        mobi_len, _, codepage, _, version = struct.unpack(">IIIII", rec0[20:40])
        ex = exth(rec0, mobi_len)
        title_off, title_len = struct.unpack(">II", rec0[84:92])
        charset = "utf-8" if codepage == 65001 else "cp1252"
        title = rec0[title_off:title_off + title_len].decode(charset, "replace")
        boundary = ex.get(121)
        kind = "KF8 (AZW3)" if version == 8 else f"MOBI {version}"
        if boundary and struct.unpack(">I", boundary)[0] != 0xFFFFFFFF:
            kind = "joint file: MOBI 6 + KF8 inside"
        lines[:0] = [f"title: {title}", f"format: {kind}",
                     f"text encoding: {ENCODING.get(codepage, codepage)}"]
        if 524 in ex:
            lines.append(f"language: {ex[524].decode('utf-8', 'replace')}")
    verdict = "OK to upload" if enc == 0 else "DRM-protected: BookTranslator will reject it"
    return "\n".join(lines + [f"verdict: {verdict}"])

if __name__ == "__main__":
    for p in sys.argv[1:]:
        try:
            result = inspect(p)
        except (struct.error, IndexError, OSError) as err:
            result = f"could not read the header ({err}); the file may be truncated or damaged"
        print(f"== {p}\n{result}\n")
