#!/usr/bin/env python
import pickle
import urllib
from shutil import copyfile
from lxml import etree
from lxml import objectify
from io import BytesIO
import os.path
import errno
import os
import pprint
import dpath.util
import hashlib
import re
import sys



from mvn_utils import read_remote_file
from mvn_utils import sha1, print_stats
from maven_package import MavenPackage
from shutil import copyfile
import shutil

buck_file = os.getcwd() + '/maven/BUCK'
buck_file_py = os.getcwd() + '/maven/buck.py'

mvn_pkg_str = """
remote_file(
    name =  '{0}',
    out = '{0}.{1}',
    sha1 = '{2}',
    url = '{3}'
)
"""

aar_str="""
android_prebuilt_aar(
    name = '{0}',
    aar = ':{0}-remote',
    deps = [
{1}    ],
    visibility = ['PUBLIC']
)
"""
jar_str="""
prebuilt_jar(
    name = '{0}',
    binary_jar = ':{0}-remote',
    deps = [
{1}    ],
    visibility = ['PUBLIC']
)
"""

local_str = """
android_prebuilt_aar(
  name = '{0}',
  aar = '{1}',
  visibility = ['PUBLIC']
)
"""
default_content = """
# THIS FILE HAS BEEN GENERATED AUTOMATICALLY
# DO NOT EDIT THIS FILE MANUALLY
# To regenerate just type `python mvn cache rebuild`
# To add a maven package type
# > python mvn package add groupId:artifactId:versionId
"""

sdkPath = os.environ.get('ANDROID_HOME')
if not sdkPath or sdkPath == '':
    print 'No SDK path specified'
    print 'Please set ANDROID_HOME var in ~/.bashrc'
    print 'Exiting...'
    exit(1)
print 'Using SDK path `{0}`'.format(sdkPath)

sys.path.insert(0, os.getcwd() + '/maven/')
packages = []

def write_buck_file():
    global packages
    content = default_content

    for package in packages:

        content += '\n\n### Package ' + package.identifier.universal_id
        if package.repository == 'local:':
            file = (sdkPath + '/extras/android/m2repository/{0}/{1}/{2}/{1}-{2}.aar'
                .format(package.group.replace('.', '/'), package.name, package.version))

            target = package.name + '-' + package.version +'.aar'
            path = os.getcwd() + '/maven/' + target
            if not os.path.isfile(path):
                copyfile(file, path)
            content += local_str.format(package.identifier.normalized_id, target)
            continue
        deps = package.get_flat_dependencies(0)
        deps_str = ''
        for dep in deps:
            if dep != package.identifier.normalized_id:
                deps_str += '        \'//maven:{0}\',\n'.format(dep)

        nid = package.identifier.normalized_id
        sha1 = package.mavensha1()
        content += mvn_pkg_str.format(
            '{0}-remote'.format(nid),
            package.extension,
            sha1,
            package.get_url(package.extension)
        )
        ar_str = aar_str if package.extension == 'aar' else jar_str
        content += ar_str.format(nid, deps_str)
    lf = open(buck_file, 'w')
    lf.write(content)
    lf.close()

do_print = False

def add_package(pkg, repo='http://repo1.maven.org/maven2/', no_cache=False, type='primary'):
    global packages
    package = MavenPackage(package = pkg,
                        repository = repo,
                        type=type)
    if type == 'primary' and do_print:
        print 'Adding {0} from {1} with{2} cache...'.format(pkg, repo,
            'out' if no_cache else '')
        print '\033[2m'
        package.display_tree()
        print '\033[0m'

    deps = package.get_flat_dependencies(1)
    # ndeps = package.get_flat_dependencies(0)

    new_packages = []

    for p in packages:
        if p.identifier.normalized_id == package.identifier.normalized_id:
            if type == 'secondary':
                if do_print:
                    # print 'Package already added.'
                    pass
                return False
            else:
                if do_print:
                    print 'Dropping secondary package in favor of primary'
                continue
        new_packages.append(p)

    packages = list(new_packages)
    for dep in deps:
        if dep != pkg:
            add_package(dep, repo, no_cache, 'secondary')
    packages.append(package)
    return True



help = """Simple utility to add new maven repos and cache them to cache

Usage:
    bucken package add <package> [--no-cache] [--repo=<repo>]
    bucken -h | --help
    bucken cache (clean)

Options:
    --repo=<repo>       Specify the repository URL
    --no-cache          Do not use cache, not implemented yet
    --help -h           Show this screen
"""

packages_file = os.getcwd() + '/maven/PACKAGES'
f = open(packages_file, 'r')
config = f.read()
found = re.findall('^compile\s(.+)\sfrom\s(.+)$', config, re.MULTILINE)
for pkg, repo in found:
    add_package(pkg, repo)

from docopt import docopt

arguments = docopt(help)

if arguments.get('cache', False):
    write_buck_file()


if arguments.get('package', False):
    if arguments.get('add', False):
        pkg = arguments.get('<package>')
        repo = arguments.get('--repo', 'http://repo1.maven.org/maven2/')
        if not repo or repo == 'None':
            repo = 'http://repo1.maven.org/maven2/'
        no_cache = arguments.get('--no-cache', False)
        do_print = True
        if add_package(pkg, repo,  no_cache):
            f = open(packages_file, 'w')
            f.write('{0}\ncompile {1} from {2}'.format(config, pkg, repo))
            f.close()
        write_buck_file()
        print_stats()
    if arguments.get('cache', False):
        shutil.rmtree(os.environ['HOME'] + '/.bucken/cache')
