# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import re
import shutil
from subprocess import Popen, PIPE
import sys
import tempfile


def run_command(*args):
    process = Popen(args, stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    if process.returncode:
        raise Exception('Command %s failed: %s' % (args, stdout + stderr))
    return stdout


def get_device_addresses(dev_finder):
    # Find a target device.
    stdout = run_command(dev_finder, 'list', '-device_limit', '1', '-full')
    match = re.match('^([^\s]+)\s+([^\s]+)$', stdout.strip())
    if not match:
        raise Exception('Could not parse target parameters in %s' % stdout)
    target_address = match.group(1)
    target_name = match.group(2)
    # TODO(DX-844): use full name.
    target_name = target_name[1:-1]

    # Get the matching host address for that device.
    stdout = run_command(dev_finder, 'resolve', '-local', target_name)
    host_address = stdout.strip()
    return target_address, host_address


def serve_package(pm, package, directory):
    # Set up the package repository.
    run_command(pm, 'newrepo', '-repo', directory)
    run_command(pm, 'publish', '-a', '-r', directory, '-f', package)

    # Start the server.
    server = Popen([pm, 'serve', '-repo', directory+'/repository'], stdout=PIPE,
                   stderr=PIPE)
    return lambda: server.kill()


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config',
                        help='The path to the list of components in the package',
                        required=True)
    parser.add_argument('--package-name',
                        help='The name of the Fuchsia package',
                        required=True)
    parser.add_argument('--package',
                        help='The path to the Fuchsia package',
                        required=True)
    parser.add_argument('--dev-finder',
                        help='The path to the dev_finder tool',
                        required=True)
    parser.add_argument('--pm',
                        help='The path to the pm tool',
                        required=True)
    subparse = parser.add_subparsers().add_parser('run')
    subparse.add_argument('component',
                          nargs=1)
    subparse.add_argument('--ssh-key',
                          help='The path to private key for SSH communications',
                          required=True)
    args = parser.parse_args()

    with open(args.config, 'r') as config_file:
        components = config_file.readlines()

    component = args.component[0]
    if component not in components:
        print('Error: "%s" not in %s' % (component, components))
        return 1

    staging_dir = tempfile.mkdtemp(prefix='fuchsia-run')

    try:
        target_address, host_address = get_device_addresses(args.dev_finder)
        stop_server = serve_package(args.pm, args.package, staging_dir)
        try:
            def run_ssh_command(*params):
                base = ['ssh', '-i', args.ssh_key, 'fuchsia@'+target_address]
                run_command(*(base + list(params)))
            server_address = 'http://%s:8083/config.json' % host_address
            run_ssh_command('amber_ctl', 'add_src', '-x', '-f', server_address)
            component_uri = "fuchsia-pkg://fuchsia.com/%s#meta/%s.cmx" % (
                    args.package_name, component)
            run_ssh_command('run', component_uri)
        finally:
            stop_server()
    except Exception as e:
        print(e)
        return 1
    finally:
        shutil.rmtree(staging_dir, ignore_errors=True)

    print('One day I will run %s from %s' % (component, args.package))

    return 0


if __name__ == '__main__':
    sys.exit(main())
