#!/usr/bin/env python3

import logging as log
import re
import subprocess
import sys
from resource import Resource


def human_readable_output(line):
    """Convert packer machine readable output to human readable output."""
    if not line:
        return None
    ts, target, out_type, data = line.split(',', 3)
    if out_type == 'ui':
        ui_type, output = data.split(',', 1)
        return output.replace('%!(PACKER_COMMA)', ',')
    else:
        return None

class PackerResource(Resource):
    """Resource implementation for packer."""

    def out_cmd(self, source, params):
        """Packer build."""

        template_path = params['template_path']
        build_vars = params.get('build_vars', {})
        build_vars_from_file = params.get('build_vars_from_file', {})

        # read build var values from files
        for k, build_var_file in build_vars_from_file.items():
            with open(build_var_file) as f:
                build_vars[k] = f.read().strip()

        # compose packer command
        cmd = ['packer', 'build', '-machine-readable']
        for k, v in build_vars.items():
            cmd += ['-var=%s=%s' % (k, v)]
        cmd.append(template_path)

        log.info('starting packer build')
        proc = subprocess.Popen(cmd, stderr=subprocess.STDOUT,
            stdout=subprocess.PIPE)
        output = ""
        while proc.poll() is None:
            line = proc.stdout.readline().decode('utf8')
            if line:
                output += line

                out = human_readable_output(line.strip())
                if out:
                    log.info(out)
        if proc.returncode != 0:
            log.error('packer build failed.')
            sys.exit(1)

        AMI_MATCH = 'artifact,0,id,(?P<region>[\w-]+):(?P<ami_id>[\w-]+)'
        version_match = re.search(AMI_MATCH, output, re.DOTALL)
        if not version_match:
            raise Exception('no AMI id in output')
        region, ami_id = version_match.groups()

        metadata = []

        TAG_MATCH = 'Adding tag: "(?P<name>[^"]+)": "(?P<value>[^"]*)"'
        for tag in re.finditer(TAG_MATCH, output, re.DOTALL):
            meta_tag = tag.groupdict()
            meta_tag['name'] = 'tag_' + meta_tag['name']
            metadata.append(meta_tag)

        return {
            'version': {
                'ImageId': ami_id,
                'Region': region,
            },
            'metadata': metadata,
        }

if __name__ == '__main__':
    print(PackerResource().run('out'))
