"""Download `Unicodedata` files."""
from __future__ import unicode_literals
import os
import zipfile
import codecs
from urllib.request import urlopen

__version__ = '2.2.0'

HOME = os.path.dirname(os.path.abspath(__file__))


def zip_unicode(output, version):
    """Zip the Unicode files."""

    zipper = zipfile.ZipFile(os.path.join(output, 'unicodedata', '%s.zip' % version), 'w', zipfile.ZIP_DEFLATED)
    target = os.path.join(output, 'unicodedata', version)

    print('Zipping %s.zip...' % version)

    for root, dirs, files in os.walk(target):
        for file in files:
            if file.endswith('.txt'):
                zipper.write(os.path.join(root, file), arcname=file)


def unzip_unicode(output, version):
    """Unzip the Unicode files."""

    unzipper = zipfile.ZipFile(os.path.join(output, 'unicodedata', '%s.zip' % version))
    target = os.path.join(output, 'unicodedata', version)

    print('Unzipping %s.zip...' % version)

    os.makedirs(target)

    for f in unzipper.namelist():
        # Do I need backslash on windows? Or is it forward as well?
        unzipper.extract(f, target)


def download_unicodedata(version, output=HOME, no_zip=False):
    """Download Unicode data scripts and blocks."""

    ver = tuple([int(x) for x in version.split('.')])

    files = [
        'UnicodeData.txt',
        'Scripts.txt',
        'Blocks.txt',
        'PropList.txt',
        'DerivedCoreProperties.txt',
        'DerivedNormalizationProps.txt',
        'CompositionExclusions.txt',
        'PropertyValueAliases.txt',
        'PropertyAliases.txt',
        'EastAsianWidth.txt',
        'LineBreak.txt',
        'HangulSyllableType.txt',
        'DerivedAge.txt',
        'auxiliary/WordBreakProperty.txt',
        'auxiliary/SentenceBreakProperty.txt',
        'auxiliary/GraphemeBreakProperty.txt',
        'extracted/DerivedDecompositionType.txt',
        'extracted/DerivedNumericType.txt',
        'extracted/DerivedNumericValues.txt',
        'extracted/DerivedJoiningType.txt',
        'extracted/DerivedJoiningGroup.txt',
        'extracted/DerivedCombiningClass.txt',
        'emoji/emoji-data.txt'
    ]

    files.append('ScriptExtensions.txt')
    files.append('IndicPositionalCategory.txt')
    files.append('IndicSyllabicCategory.txt')
    files.append('BidiBrackets.txt')

    if ver >= (11, 0, 0):
        files.append('VerticalOrientation.txt')

    http_url = 'http://www.unicode.org/Public/%s/ucd/' % version
    ftp_url = 'ftp://ftp.unicode.org/Public/%s/ucd/' % version

    destination = os.path.join(output, 'unicodedata', version)
    if not os.path.exists(destination):
        os.makedirs(destination)

    zip_data = not no_zip

    for f in files:
        file_location = os.path.join(destination, os.path.basename(f))
        retrieved = False
        if not os.path.exists(file_location):
            for url in (ftp_url, http_url):
                furl = url + f
                try:
                    print('Downloading: %s --> %s' % (furl, file_location))
                    response = urlopen(furl, timeout=30)
                    data = response.read()
                except Exception:
                    print('Failed: %s' % url)
                    continue
                with codecs.open(file_location, 'w', encoding='utf-8') as uf:
                    uf.write(data.decode('utf-8'))
                retrieved = True
                break
            if not retrieved:
                print('Failed to acquire all needed Unicode files!')
                break
        else:
            retrieved = True
            print('Skipping: found %s' % file_location)

        if not retrieved:
            zip_data = False
            break

    if zip_data and not os.path.exists(os.path.join(output, 'unicodedata', '%s.zip' % version)):
        zip_unicode(output, version)


def get_unicodedata(version, output=HOME, no_zip=False):
    """Ensure we have Unicode data to generate Unicode tables."""

    target = os.path.join(output, 'unicodedata', version)
    zip_target = os.path.join(output, 'unicodedata', '%s.zip' % version)

    if not os.path.exists(target) and os.path.exists(zip_target):
        unzip_unicode(output, version)

    # Download missing files if any. Zip if required.
    download_unicodedata(version, output, no_zip)


if __name__ == '__main__':
    import argparse
    import unicodedata

    parser = argparse.ArgumentParser(prog='unidatadownload', description='Generate a unicode property table.')
    parser.add_argument('--version', action='version', version="%(prog)s " + __version__)
    parser.add_argument('--output', default=HOME, help='Output file.')
    parser.add_argument('--unicode-version', default=None, help='Force a specific Unicode version.')
    args = parser.parse_args()

    if args.unicode_version is None:
        version = unicodedata.unidata_version
    else:
        version = args.unicode_version

    get_unicodedata(version, output=args.output)

[(10, 'os.path.abspath', 'os.path.abspath', False, 'import os\n'), (17, 'os.path.join', 'os.path.join', False, 'import os\n'), (21, 'os.walk', 'os.walk', False, 'import os\n'), (31, 'os.path.join', 'os.path.join', False, 'import os\n'), (35, 'os.makedirs', 'os.makedirs', False, 'import os\n'), (84, 'os.path.join', 'os.path.join', False, 'import os\n'), (125, 'os.path.join', 'os.path.join', False, 'import os\n'), (126, 'os.path.join', 'os.path.join', False, 'import os\n'), (139, 'argparse.ArgumentParser', 'argparse.ArgumentParser', False, 'import argparse\n'), (16, 'os.path.join', 'os.path.join', False, 'import os\n'), (30, 'os.path.join', 'os.path.join', False, 'import os\n'), (85, 'os.path.exists', 'os.path.exists', False, 'import os\n'), (86, 'os.makedirs', 'os.makedirs', False, 'import os\n'), (128, 'os.path.exists', 'os.path.exists', False, 'import os\n'), (91, 'os.path.basename', 'os.path.basename', False, 'import os\n'), (93, 'os.path.exists', 'os.path.exists', False, 'import os\n'), (128, 'os.path.exists', 'os.path.exists', False, 'import os\n'), (118, 'os.path.join', 'os.path.join', False, 'import os\n'), (24, 'os.path.join', 'os.path.join', False, 'import os\n'), (98, 'urllib.request.urlopen', 'urlopen', False, 'from urllib.request import urlopen\n'), (103, 'codecs.open', 'codecs.open', False, 'import codecs\n')]