#!/usr/bin/env python
import os
import sys
import re
import logging
import subprocess
import argparse

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

from wlauto.exceptions import WAError, ToolError
from wlauto.utils.doc import format_simple_table


def get_aapt_path():
    """Return the full path to aapt tool."""
    sdk_path = os.getenv('ANDROID_HOME')
    if not sdk_path:
        raise ToolError('Please make sure you have Android SDK installed and have ANDROID_HOME set.')
    build_tools_directory = os.path.join(sdk_path, 'build-tools')
    versions = os.listdir(build_tools_directory)
    for version in reversed(sorted(versions)):
        aapt_path = os.path.join(build_tools_directory, version, 'aapt')
        if os.path.isfile(aapt_path):
            logging.debug('Found aapt for version {}'.format(version))
            return aapt_path
    else:
        raise ToolError('aapt not found. Please make sure at least one Android platform is installed.')


def get_apks(path):
    """Return a list of paths to all APK files found under the specified directory."""
    apks = []
    for root, dirs, files in os.walk(path):
        for file in files:
            _, ext = os.path.splitext(file)
            if ext.lower() == '.apk':
                apks.append(os.path.join(root, file))
    return apks


class ApkVersionInfo(object):

    def __init__(self, workload=None, package=None, label=None, version_name=None, version_code=None):
        self.workload = workload
        self.package = package
        self.label = label
        self.version_name = version_name
        self.version_code = version_code

    def to_tuple(self):
        return (self.workload, self.package, self.label, self.version_name, self.version_code)


version_regex = re.compile(r"name='(?P<name>[^']+)' versionCode='(?P<vcode>[^']+)' versionName='(?P<vname>[^']+)'")


def extract_version_info(apk_path, aapt):
    command = [aapt, 'dump', 'badging', apk_path]
    output = subprocess.check_output(command)
    version_info = ApkVersionInfo(workload=apk_path.split(os.sep)[-2])
    for line in output.split('\n'):
        if line.startswith('application-label:'):
            version_info.label = line.split(':')[1].strip().replace('\'', '')
        elif line.startswith('package:'):
            match = version_regex.search(line)
            if match:
                version_info.package = match.group('name')
                version_info.version_code = match.group('vcode')
                version_info.version_name = match.group('vname')
        else:
            pass  # not interested
    return version_info


def get_apk_versions(path, aapt):
    apks = get_apks(path)
    versions = [extract_version_info(apk, aapt) for apk in apks]
    return versions


if __name__ == '__main__':
    try:
        aapt = get_aapt_path()
        parser = argparse.ArgumentParser()
        parser.add_argument('path', metavar='PATH', help='Location to look for APKs.')
        args = parser.parse_args()

        versions = get_apk_versions(args.path, aapt)
        table = format_simple_table([v.to_tuple() for v in versions],
                                    align='<<<>>',
                                    headers=['workload', 'package', 'name', 'version code', 'version name'])
        print table
    except WAError, e:
        logging.error(e)
        sys.exit(1)