#!/usr/bin/env python3.3
from __future__ import division, with_statement, print_function

from contextlib import closing
import json
import os
import sys
import tarfile
from urllib.request import urlopen
from threading import Thread
import subprocess

def makefolder(path):
    dirname = os.path.dirname(path)
    if not os.path.exists(dirname):
        os.makedirs(dirname)

class Install(Thread):

    base_url = 'http://downloads.openmedialibrary.com/'
    status = {}

    def __init__(self, target):
        self.target = target
        Thread.__init__(self)
        self.daemon = True
        self.start()

    def run(self):
        target = self.target
        target = os.path.normpath(os.path.join(os.path.abspath(target)))
        if not os.path.exists(target):
            os.makedirs(target)
        os.chdir(target)
        release = self.get_release()
        self.status['release'] = release
        for module in release['modules']:
            self.status['installing'] = module
            self.status['progress'] = 0
            self.status['size'] = 0
            package_tar = release['modules'][module]['name']
            url = self.url(package_tar)
            package_tar = os.path.join(self.target, package_tar)
            self.download(url, package_tar)
            tar = tarfile.open(package_tar)
            tar.extractall()
            tar.close()
            os.unlink(package_tar)
        os.symlink('openmedialibrary/ctl', 'ctl')
        self.status['progress'] = 0
        self.status['installing'] = 'setup'
        if sys.platform.startswith('linux'):
            apt_packages = ''
            dnf_packages = ''
            try:
                from PIL import Image
                import lxml
            except:
                apt_packages += ' python3.4 python3-pil python3-lxml'
                dnf_packages += ' python3-pillow python3-lxml'
            try:
                import gi
                gi.require_version('WebKit2', '4.0')
                from gi.repository import WebKit2, Gtk
            except:
                apt_packages += ' gir1.2-webkit2-4.0'
                dnf_packages += ' webkitgtk4'
            try:
                import OpenSSL
            except:
                apt_packages += ' python3-openssl'
                dnf_packages += ' python3-pyOpenSSL'
            try:
                import Crypto
            except:
                apt_packages += ' python3-crypto'
                dnf_packages += ' python3-pyCrypto'

            if not has_bin('pdftocairo'):
                apt_packages += ' poppler-utils'
                dnf_packages += ' poppler-utils'
            if not os.path.exists('/usr/sbin/miredo'):
                apt_packages += ' miredo'
                dnf_packages += ' miredo-client'

            if has_bin('apt-get') and apt_packages:
                print('Installing additional packages: %s' % apt_packages)
                os.system('sudo apt-get install -y ' + apt_packages)
            elif has_bin('dnf') and dnf_packages:
                print('Installing additional packages: %s' % dnf_packages)
                os.system('sudo dnf install -y ' + dnf_packages)
            else:
                print('You need to install Pillow, lxml and pyOpenSSL\ni.e. sudo pip3 install pillow lxml pyOpenSSL')
                if 'poppler' in apt_packages:
                    print('You need to install pdftocairo (part of poppler-utils)')
                if 'miredo' in apt_packages:
                    print('You need to install miredo (or get IPv6 in another way)')
                input("After installing those packages, press Enter to continue...")
            os.system('./ctl install_launcher')
        os.system('./ctl setup')
        self.status['progress'] = 1
        with open('config/release.json', 'w') as fd:
            json.dump(release, fd, indent=2)
        self.status['done'] = True

    def download(self, url, filename):
        makefolder(filename)
        print(os.path.basename(filename))
        with open(filename, 'wb') as f:
            with closing(urlopen(url)) as u:
                size = int(u.headers.get('content-length', 0))
                self.status['size'] = size
                available = 0
                data = u.read(4096)
                while data:
                    if size:
                        available += len(data)
                        self.status['progress'] = available/size
                    f.write(data)
                    data = u.read(4096)

    def get_release(self):
        with closing(urlopen(self.url('release.json'))) as u:
            data = json.loads(u.read().decode('utf-8'))
        return data

    def url(self, url):
        return self.base_url + url

def has_bin(cmd):
    return subprocess.call(['which', cmd], stdout=subprocess.PIPE) == 0

if __name__ == '__main__':
    if sys.version_info[:2] != (3,4):
        print("You need python3.4")
        sys.exit(1)
    if len(sys.argv) == 1:
        if sys.platform == 'darwin':
            target = os.path.expanduser('~/Library/Application Support/Open Media Libary')
        elif sys.platform.startswith('linux'):
            target = os.path.expanduser('~/.local/share/openmedialibrary')
        else:
            target = os.path.join(os.curdir, 'openmedialibrary')
    elif len(sys.argv) != 2:
        print('usage: %s [target]' % sys.argv[0])
        sys.exit(1)
    else:
        target = sys.argv[1]
    if os.path.exists(target):
        print('%s exists, remove it before re-installing Open Media Library' % target)
        sys.exit(1)
    install = Install(target)
    install.join()
    subprocess.call([os.path.join(target, 'ctl'), 'open'])