# 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.

import logging
import os
import remote_cmd
import subprocess
import sys
import tempfile
import time

_SHUTDOWN_CMD = ['dm', 'poweroff']
_ATTACH_MAX_RETRIES = 10
_ATTACH_RETRY_INTERVAL = 1


class FuchsiaTargetException(Exception):
  def __init__(self, message):
    super(FuchsiaTargetException, self).__init__(message)


class Target(object):
  """Base class representing a Fuchsia deployment target."""

  def __init__(self, output_dir, target_cpu):
    self._output_dir = output_dir
    self._started = False
    self._dry_run = False
    self._target_cpu = target_cpu

  # Functions used by the Python context manager for teardown.
  def __enter__(self):
    return self
  def __exit__(self, exc_type, exc_val, exc_tb):
    return self

  def Start(self):
    """Handles the instantiation and connection process for the Fuchsia
    target instance."""

    pass

  def IsStarted(self):
    """Returns True if the Fuchsia target instance is ready to accept
    commands."""

    return self._started

  def IsNewInstance(self):
    """Returns True if the connected target instance is newly provisioned."""

    return True

  def RunCommandPiped(self, command, **kwargs):
    """Starts a remote command and immediately returns a Popen object for the
    command. The caller may interact with the streams, inspect the status code,
    wait on command termination, etc.

    command: A list of strings representing the command and arguments.
    kwargs: A dictionary of parameters to be passed to subprocess.Popen().
            The parameters can be used to override stdin and stdout, for
            example.

    Returns: a Popen object.

    Note: method does not block."""

    self._AssertIsStarted()
    logging.debug('running (non-blocking) \'%s\'.' % ' '.join(command))
    host, port = self._GetEndpoint()
    return remote_cmd.RunPipedSsh(self._GetSshConfigPath(), host, port, command,
                                  **kwargs)

  def RunCommand(self, command, silent=False):
    """Executes a remote command and waits for it to finish executing.

    Returns the exit code of the command."""

    self._AssertIsStarted()
    logging.debug('running \'%s\'.' % ' '.join(command))
    host, port = self._GetEndpoint()
    return remote_cmd.RunSsh(self._GetSshConfigPath(), host, port, command,
                             silent)

  def PutFile(self, source, dest, recursive=False):
    """Copies a file from the local filesystem to the target filesystem.

    source: The path of the file being copied.
    dest: The path on the remote filesystem which will be copied to.
    recursive: If true, performs a recursive copy."""

    assert type(source) is str
    self.PutFiles([source], dest, recursive)

  def PutFiles(self, sources, dest, recursive=False):
    """Copies files from the local filesystem to the target filesystem.

    sources: List of local file paths to copy from, or a single path.
    dest: The path on the remote filesystem which will be copied to.
    recursive: If true, performs a recursive copy."""

    assert type(sources) is tuple or type(sources) is list
    self._AssertIsStarted()
    host, port = self._GetEndpoint()
    logging.debug('copy local:%s => remote:%s' % (sources, dest))
    command = remote_cmd.RunScp(self._GetSshConfigPath(), host, port,
                                sources, dest, remote_cmd.COPY_TO_TARGET,
                                recursive)

  def GetFile(self, source, dest):
    """Copies a file from the target filesystem to the local filesystem.

    source: The path of the file being copied.
    dest: The path on the local filesystem which will be copied to."""
    assert type(source) is str
    self.GetFiles([source], dest)

  def GetFiles(self, sources, dest):
    """Copies files from the target filesystem to the local filesystem.

    sources: List of remote file paths to copy.
    dest: The path on the local filesystem which will be copied to."""
    assert type(sources) is tuple or type(sources) is list
    self._AssertIsStarted()
    host, port = self._GetEndpoint()
    logging.debug('copy remote:%s => local:%s' % (sources, dest))
    return remote_cmd.RunScp(self._GetSshConfigPath(), host, port,
                             sources, dest, remote_cmd.COPY_FROM_TARGET)

  def _GetEndpoint(self):
    """Returns a (host, port) tuple for the SSH connection to the target."""
    raise NotImplementedError

  def _GetTargetSdkArch(self):
    """Returns the Fuchsia SDK architecture name for the target CPU."""
    if self._target_cpu == 'arm64':
      return 'aarch64'
    elif self._target_cpu == 'x64':
      return 'x86_64'
    raise FuchsiaTargetException('Unknown target_cpu:' + self._target_cpu)

  def _AssertIsStarted(self):
    assert self.IsStarted()

  def _WaitUntilReady(self, retries=_ATTACH_MAX_RETRIES):
    logging.info('Connecting to Fuchsia using SSH.')
    for _ in xrange(retries+1):
      host, port = self._GetEndpoint()
      if remote_cmd.RunSsh(self._GetSshConfigPath(), host, port, ['true'],
                           True) == 0:
        logging.info('Connected!')
        self._started = True
        return True
      time.sleep(_ATTACH_RETRY_INTERVAL)
    logging.error('Timeout limit reached.')
    raise FuchsiaTargetException('Couldn\'t connect using SSH.')

  def _GetSshConfigPath(self, path):
    raise NotImplementedError

  def _GetTargetSdkArch(self):
    """Returns the Fuchsia SDK architecture name for the target CPU."""
    if self._target_cpu == 'arm64':
      return 'aarch64'
    elif self._target_cpu == 'x64':
      return 'x86_64'
    raise Exception('Unknown target_cpu %s:' % self._target_cpu)
