#!/usr/bin/env python
# Copyright 2017 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 errno
import json
import os
import subprocess
import sys
import tempfile

DEFAULT_DST_ROOT = '/system'
DEFAULT_OUT_DIR = 'out/debug-x86-64'


def netaddr_cmd(out_dir, device):
  path = os.path.join(out_dir, '../build-magenta/tools/netaddr')
  command = [
      path,
      '--fuchsia',
      device,
  ]
  return command


def mkdir_p(path):
  try:
    os.makedirs(path)
  except OSError as exc:  # Python >2.5
    if exc.errno == errno.EEXIST and os.path.isdir(path):
      pass
    else:
      raise


def parse_package_file(package_file_path):
  with open(package_file_path) as package_file:
    data = json.load(package_file)
  return data


def update_device(device, batch_file, verbose, out_dir):
  ssh_config_path = os.path.join(out_dir, 'ssh-keys', 'ssh_config')

  try:
    netaddr = netaddr_cmd(out_dir, device)
    ipv6 = '[' + subprocess.check_output(netaddr).strip() + ']'
  except subprocess.CalledProcessError:
    # netaddr prints its own errors, no need to add another one here.
    return 1

  with open(os.devnull, 'w') as devnull:
    status = subprocess.call(
        ['sftp', '-F', ssh_config_path, '-b', batch_file, ipv6],
        stdout=sys.stdout if verbose else devnull)
    if status != 0:
      print >> sys.stderr, 'error: sftp failed'

    return status


def scp_everything(devices, package_data, out_dir, dst_root, name_filter,
                   verbose):
  # Temporary file for sftp
  with tempfile.NamedTemporaryFile() as f:
    # Create a directory tree that mirrors what we want on the device.
    for binary in package_data['binaries']:
      binary_name = binary['binary']
      if name_filter is not None and name_filter not in binary_name:
        continue

      src_path = os.path.join(out_dir, binary_name)
      device_path = os.path.join(dst_root, binary['bootfs_path'].lstrip('/'))

      # must "rm" the file first because memfs requires it
      print >> f, '-rm %s' % device_path
      print >> f, 'put -P %s %s' % (src_path, device_path)

    f.flush()

    for device in devices:
      if update_device(device, f.name, verbose, out_dir) == 0:
        print 'Updated %d files on "%s".' % (len(package_data['binaries']), device)
      else:
        print 'Update FAILED on "%s"' % device

  return 0


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('package_file', help='JSON file containing package data')
  parser.add_argument(
      'device', default=[':'], nargs='*', help='Device to update')
  parser.add_argument(
      '-o',
      '--out-dir',
      metavar='DIR',
      default=DEFAULT_OUT_DIR,
      help='Directory containing build products')
  parser.add_argument(
      '-d',
      '--dst-root',
      metavar='PATH',
      default=DEFAULT_DST_ROOT,
      help='Path on device to the directory to copy package products')
  parser.add_argument(
      '-f',
      '--filter',
      metavar='FILTER',
      help='Push products with a name that contains FILTER')
  parser.add_argument(
      '-v', '--verbose', action='store_true', help='Display copy filenames')

  args = parser.parse_args()

  package_data = parse_package_file(args.package_file)
  out_dir = args.out_dir or DEFAULT_OUT_DIR
  dst_root = args.dst_root or DEFAULT_DST_ROOT
  name_filter = args.filter
  verbose = args.verbose

  return scp_everything(args.device, package_data, out_dir, dst_root,
                        name_filter, verbose)


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