#!/usr/bin/env python
from logging.handlers import SysLogHandler
from netrc import netrc
from os import close as close_fd, listdir, makedirs, remove as rm
from os.path import basename, dirname, expanduser, isdir, join as path_join, realpath, splitext
from tempfile import mkstemp
import argparse
import logging
import signal
import sys

from osext.argparse_actions import ReadableDirectoryAction
import requests

syslogh = None


def cleanup():
    global syslogh

    if syslogh:
        syslogh.close()

    logging.shutdown()


def cleanup_and_exit(status=0):
    cleanup()
    sys.exit(status)


def ctrl_c(signum, frame):
    cleanup()
    raise SystemExit('Signal raised')


if __name__ == '__main__':
    signal.signal(signal.SIGINT, ctrl_c)

    cache_dir = realpath(expanduser('~/.cache/xirvik'))

    if not isdir(cache_dir):
        makedirs(cache_dir)

    log = logging.getLogger('xirvik-start-torrents')
    parser = argparse.ArgumentParser()

    parser.add_argument('-d', '--debug', action='store_true')
    parser.add_argument('-v', '--verbose', action='store_true')
    parser.add_argument('-c', '--netrc-path', default=expanduser('~/.netrc'))
    # parser.add_argument('-C', '--client', default='rutorrent3')
    parser.add_argument('-H', '--host', nargs=1, required=True)
    parser.add_argument('-p', '--port', nargs=1, default=[443])
    parser.add_argument('--start-stopped', action='store_true')
    parser.add_argument('directory',
                        metavar='DIRECTORY',
                        action=ReadableDirectoryAction)
    parser.add_argument('-s', '--syslog', action='store_true')

    args = parser.parse_args()
    user, _, password = netrc(args.netrc_path).authenticators(args.host[0])

    verbose = args.debug or args.verbose
    log.setLevel(logging.INFO)

    if verbose:
        channel = logging.StreamHandler(sys.stdout if args.verbose else sys.stderr)

        channel.setFormatter(logging.Formatter('%(asctime)s - %(message)s'))
        channel.setLevel(logging.INFO if args.verbose else logging.DEBUG)
        log.addHandler(channel)

        if args.debug:
            log.setLevel(logging.DEBUG)

    if args.syslog:
        try:
            syslogh = SysLogHandler(address='/dev/log')
        except FileNotFoundError:
            syslogh = SysLogHandler(address='/var/run/syslog')

        syslogh.setFormatter(logging.Formatter('%(message)s'))
        syslogh.setLevel(logging.DEBUG if args.debug else logging.INFO)
        log.addHandler(syslogh)

    post_url = ('https://{host:s}:{port:d}/rtorrent/php/'
                'addtorrent.php?'.format(host=args.host[0], port=args.port[0]))
    form_data = {}
    exceptions_caught = []

    # rtorrent2/3 params
    # dir_edit - ?
    # tadd_label - Label for the torrents, more param: label=
    # torrent_file - Torrent file blob data

    if args.start_stopped:
        form_data['torrents_start_stopped'] = 'on'

    for item in listdir(args.directory):
        if not item.lower().endswith('.torrent'):
            continue

        item = path_join(args.directory, item)

        # Workaround for surrogates not allowed error, rename the file
        prefix = '{n:s}-'.format(n=splitext(basename(item))[0])
        fd, name = mkstemp(dir=cache_dir, prefix=prefix, suffix='.torrent')
        with open(name, 'wb') as w:
            with open(item, 'rb') as r:
                w.write(r.read())
        old = item
        item = name

        rm(old)
        close_fd(fd)

        with open(item, 'rb') as f:
            files = dict(torrent_file=f)
            log.info('Uploading torrent {}'.format(item))
            r = requests.post(post_url, data=form_data, files=files)

            try:
                r.raise_for_status()
            except Exception as e:
                log.error('Caught exception: {e!s}'.format(e))

    if exceptions_caught:
        log.error('Exceptions caught, exiting with failure status')
        sys.exit(1)
