#!/usr/bin/env python3

import os, sys, argparse, subprocess, magic, shutil
from pathlib import Path
from getpass import getpass

parser = argparse.ArgumentParser(prog='knock', description='Convert an ACSM file to a DRM-free EPUB file')
parser.add_argument('acsm_file', metavar='file', type=str, help='the ACSM file to convert')
args = parser.parse_args()

# these are all Path objects: https://docs.python.org/3/library/pathlib.html
args.acsm_file = Path(args.acsm_file).expanduser().resolve()
args.drm_file = args.acsm_file.with_suffix('.drm')
args.epub_file = args.acsm_file.with_suffix('.epub')
args.adobe_dir = Path('~/.config/knock').expanduser()

if not args.acsm_file.exists():
    sys.exit(f'ERROR: {str(args.acsm_file)} does not exist.')

if args.epub_file.exists():
    sys.exit(f'ERROR: {str(args.epub_file)} already exists.')

if args.drm_file.exists():
    sys.exit(f'ERROR: {str(args.drm_file)} must be moved or deleted.')    

if not args.adobe_dir.exists():
    print('This device is not registered with Adobe.')
    email = input("Enter your Adobe account's email address: ")
    password = getpass("Enter your Adobe account's password: ")
    print('Registering this device with Adobe...')
    
    result = subprocess.run([
        'adept-register',
        '-u', email,
        '-O', str(args.adobe_dir)
    ], input=password.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    if result.stdout.decode().strip().startswith('Exception code : 0x1003'):
        shutil.rmtree(str(args.adobe_dir))
        sys.exit('ERROR: Incorrect password')

    if result.stdout.decode().strip().startswith('Exception code : 0x500a'):
        shutil.rmtree(str(args.adobe_dir))
        sys.exit('ERROR: No internet access')

    if result.returncode != 0 or not args.adobe_dir.exists() or result.stdout.decode().strip().startswith('Exception code : '):
        if args.adobe_dir.exists():
            shutil.rmtree(str(args.adobe_dir))
        print('ERROR: ', file=sys.stderr)
        sys.exit(result)

print('Downloading the EPUB file from Adobe...')

result = subprocess.run([
    'adept-download',
    '-d', str(args.adobe_dir.joinpath('device.xml')),
    '-a', str(args.adobe_dir.joinpath('activation.xml')),
    '-k', str(args.adobe_dir.joinpath('devicesalt')),
    '-o', str(args.drm_file),
    '-f', str(args.acsm_file)
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

if result.stdout.decode().strip().startswith('Exception code : 0x500a'):
    sys.exit('ERROR: No internet access')

if result.returncode != 0 or not args.drm_file.exists():
    print('ERROR: ', file=sys.stderr)
    sys.exit(result)

drm_file_type = magic.from_file(str(args.drm_file), mime=True)
if drm_file_type != 'application/epub+zip':
    sys.exit(f'Received a file of type:\n{drm_file_type}\nKnock only supports EPUB files.')

print('Decrypting the file...')

result = subprocess.run([
    'inept-epub',
    str(args.adobe_dir.joinpath('activation.xml')),
    str(args.drm_file),
    str(args.epub_file)
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

if result.returncode != 0 or not args.epub_file.exists():
    print('ERROR: ', file=sys.stderr)
    sys.exit(result)

args.drm_file.unlink()

print(f'\nDRM-free EPUB file created:\n{str(args.epub_file)}')