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

"""Functions used to provision Fuchsia boot images."""

import common
import logging
import os
import subprocess
import tempfile
import time
import uuid

_SSH_CONFIG_TEMPLATE = """
Host *
  CheckHostIP no
  StrictHostKeyChecking no
  ForwardAgent no
  ForwardX11 no
  UserKnownHostsFile {known_hosts}
  User fuchsia
  IdentitiesOnly yes
  IdentityFile {identity}
  ServerAliveInterval 1
  ServerAliveCountMax 1
  ControlMaster auto
  ControlPersist 1m
  ControlPath /tmp/ssh-%r@%h:%p"""

FVM_TYPE_QCOW = 'qcow'
FVM_TYPE_SPARSE = 'sparse'


def _TargetCpuToSdkBinPath(target_arch):
  """Returns the path to the SDK 'target' file directory for |target_cpu|."""

  return os.path.join(common.SDK_ROOT, 'target', target_arch)


def _ProvisionSSH(output_dir):
  """Provisions the key files used by the SSH daemon, and generates a
  configuration file used by clients for connecting to SSH.

  Returns a tuple with:
  #0: the client configuration file
  #1: a list of file path pairs: (<path in image>, <path on build filesystem>).
  """

  host_key_path = output_dir + '/ssh_key'
  host_pubkey_path = host_key_path + '.pub'
  id_key_path = output_dir + '/id_ed25519'
  id_pubkey_path = id_key_path + '.pub'
  known_hosts_path = output_dir + '/known_hosts'
  ssh_config_path = GetSSHConfigPath(output_dir)

  logging.debug('Generating SSH credentials.')
  if not os.path.isfile(host_key_path):
    subprocess.check_call(['ssh-keygen', '-t', 'ed25519', '-h', '-f',
                           host_key_path, '-P', '', '-N', ''],
                          stdout=open(os.devnull))
  if not os.path.isfile(id_key_path):
    subprocess.check_call(['ssh-keygen', '-t', 'ed25519', '-f', id_key_path,
                           '-P', '', '-N', ''], stdout=open(os.devnull))

  with open(ssh_config_path, "w") as ssh_config:
    ssh_config.write(
        _SSH_CONFIG_TEMPLATE.format(identity=id_key_path,
                                    known_hosts=known_hosts_path))

  if os.path.exists(known_hosts_path):
    os.remove(known_hosts_path)

  return (
      ssh_config_path,
      (('ssh/ssh_host_ed25519_key', host_key_path),
       ('ssh/ssh_host_ed25519_key.pub', host_pubkey_path),
       ('ssh/authorized_keys', id_pubkey_path))
  )


def _MakeQcowDisk(output_dir, disk_path):
  """Creates a QEMU copy-on-write version of |disk_path| in the output
  directory."""

  qimg_path = os.path.join(common.SDK_ROOT, 'qemu', 'bin', 'qemu-img')
  output_path = os.path.join(output_dir,
                             os.path.basename(disk_path) + '.qcow2')
  subprocess.check_call([qimg_path, 'create', '-q', '-f', 'qcow2',
                         '-b', disk_path, output_path])
  return output_path


def GetTargetFile(target_arch, filename):
  """Computes a path to |filename| in the Fuchsia target directory specific to
  |target_arch|."""

  return os.path.join(_TargetCpuToSdkBinPath(target_arch), filename)


def GetSSHConfigPath(output_dir):
  return output_dir + '/ssh_config'


def ConfigureDataFVM(output_dir, output_type):
  """Builds the FVM image for the /data volume and prepopulates it
  with SSH keys.

  output_dir: Path to the output directory which will contain the FVM file.
  output_type: If FVM_TYPE_QCOW, then returns a path to the qcow2 FVM file,
               used for QEMU.

               If FVM_TYPE_SPARSE, then returns a path to the
               sparse/compressed FVM file."""

  logging.debug('Building /data partition FVM file.')
  with tempfile.NamedTemporaryFile() as data_file:
    # Build up the minfs partition data and install keys into it.
    ssh_config, ssh_data = _ProvisionSSH(output_dir)
    with tempfile.NamedTemporaryFile() as manifest:
      for dest, src in ssh_data:
        manifest.write('%s=%s\n' % (dest, src))
      manifest.flush()
      minfs_path = os.path.join(common.SDK_ROOT, 'tools', 'minfs')
      subprocess.check_call([minfs_path, '%s@1G' % data_file.name, 'create'])
      subprocess.check_call([minfs_path, data_file.name, 'manifest',
                             manifest.name])

      # Wrap the minfs partition in a FVM container.
      fvm_path = os.path.join(common.SDK_ROOT, 'tools', 'fvm')
      fvm_output_path = os.path.join(output_dir, 'fvm.data.blk')
      if os.path.exists(fvm_output_path):
        os.remove(fvm_output_path)

      if output_type == FVM_TYPE_SPARSE:
        cmd = [fvm_path, fvm_output_path, 'sparse', '--compress', 'lz4',
               '--data', data_file.name]
      else:
        cmd = [fvm_path, fvm_output_path, 'create', '--data', data_file.name]

      logging.debug(' '.join(cmd))
      subprocess.check_call(cmd)

      if output_type == FVM_TYPE_SPARSE:
        return fvm_output_path
      elif output_type == FVM_TYPE_QCOW:
        return _MakeQcowDisk(output_dir, fvm_output_path)
      else:
        raise Exception('Unknown output_type: %r' % output_type)


def GetNodeName(output_dir):
  """Returns the cached Zircon node name, or generates one if it doesn't
  already exist. The node name is used by Discover to find the prior
  deployment on the LAN."""

  nodename_file = os.path.join(output_dir, 'nodename')
  if not os.path.exists(nodename_file):
    nodename = uuid.uuid4()
    f = open(nodename_file, 'w')
    f.write(str(nodename))
    f.flush()
    f.close()
    return str(nodename)
  else:
    f = open(nodename_file, 'r')
    return f.readline()


def GetKernelArgs(output_dir):
  return ['devmgr.epoch=%d' % time.time(),
          'zircon.nodename=' + GetNodeName(output_dir)]
