# -*- coding: utf-8 -*-
# Copyright (c) 2014-2015 The ChromiumOS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Download images from Cloud Storage."""

from __future__ import print_function

import ast
import os

import test_flag

from cros_utils import command_executer

GS_UTIL = 'src/chromium/depot_tools/gsutil.py'


class MissingImage(Exception):
  """Raised when the requested image does not exist in gs://"""


class MissingFile(Exception):
  """Raised when the requested file does not exist in gs://"""


class RunCommandExceptionHandler(object):
  """Handle Exceptions from calls to RunCommand"""

  def __init__(self, logger_to_use, log_level, cmd_exec, command):
    self.logger = logger_to_use
    self.log_level = log_level
    self.ce = cmd_exec
    self.cleanup_command = command

  def HandleException(self, _, e):
    # Exception handler, Run specified command
    if self.log_level != 'verbose' and self.cleanup_command is not None:
      self.logger.LogOutput('CMD: %s' % self.cleanup_command)
    if self.cleanup_command is not None:
      _ = self.ce.RunCommand(self.cleanup_command)
    # Raise exception again
    raise e


class ImageDownloader(object):
  """Download images from Cloud Storage."""

  def __init__(self, logger_to_use=None, log_level='verbose', cmd_exec=None):
    self._logger = logger_to_use
    self.log_level = log_level
    self._ce = cmd_exec or command_executer.GetCommandExecuter(
        self._logger, log_level=self.log_level)

  def GetBuildID(self, chromeos_root, xbuddy_label):
    # Get the translation of the xbuddy_label into the real Google Storage
    # image name.
    command = ('cd /mnt/host/source/src/third_party/toolchain-utils/crosperf; '
               "./translate_xbuddy.py '%s'" % xbuddy_label)
    _, build_id_tuple_str, _ = self._ce.ChrootRunCommandWOutput(
        chromeos_root, command)
    if not build_id_tuple_str:
      raise MissingImage("Unable to find image for '%s'" % xbuddy_label)

    build_id_tuple = ast.literal_eval(build_id_tuple_str)
    build_id = build_id_tuple[0]

    return build_id

  def DownloadImage(self, chromeos_root, build_id, image_name):
    if self.log_level == 'average':
      self._logger.LogOutput('Preparing to download %s image to local '
                             'directory.' % build_id)

    # Make sure the directory for downloading the image exists.
    download_path = os.path.join(chromeos_root, 'chroot/tmp', build_id)
    image_path = os.path.join(download_path, 'chromiumos_test_image.bin')
    if not os.path.exists(download_path):
      os.makedirs(download_path)

    # Check to see if the image has already been downloaded.  If not,
    # download the image.
    if not os.path.exists(image_path):
      gsutil_cmd = os.path.join(chromeos_root, GS_UTIL)
      command = '%s cp %s %s' % (gsutil_cmd, image_name, download_path)

      if self.log_level != 'verbose':
        self._logger.LogOutput('CMD: %s' % command)
      status = self._ce.RunCommand(command)
      downloaded_image_name = os.path.join(download_path,
                                           'chromiumos_test_image.tar.xz')
      if status != 0 or not os.path.exists(downloaded_image_name):
        raise MissingImage('Cannot download image: %s.' % downloaded_image_name)

    return image_path

  def UncompressImage(self, chromeos_root, build_id):
    # Check to see if the file has already been uncompresssed, etc.
    if os.path.exists(
        os.path.join(chromeos_root, 'chroot/tmp', build_id,
                     'chromiumos_test_image.bin')):
      return

    # Uncompress and untar the downloaded image.
    download_path = os.path.join(chromeos_root, 'chroot/tmp', build_id)
    command = ('cd %s ; tar -Jxf chromiumos_test_image.tar.xz ' % download_path)
    # Cleanup command for exception handler
    clean_cmd = ('cd %s ; rm -f chromiumos_test_image.bin ' % download_path)
    exception_handler = RunCommandExceptionHandler(self._logger, self.log_level,
                                                   self._ce, clean_cmd)
    if self.log_level != 'verbose':
      self._logger.LogOutput('CMD: %s' % command)
      print('(Uncompressing and un-tarring may take a couple of minutes...'
            'please be patient.)')
    retval = self._ce.RunCommand(
        command, except_handler=exception_handler.HandleException)
    if retval != 0:
      if self.log_level != 'verbose':
        self._logger.LogOutput('CMD: %s' % clean_cmd)
        print('(Removing file chromiumos_test_image.bin.)')
      # Remove partially uncompressed file
      _ = self._ce.RunCommand(clean_cmd)
      # Raise exception for failure to uncompress
      raise MissingImage('Cannot uncompress image: %s.' % build_id)

    # Remove compressed image
    command = ('cd %s ; rm -f chromiumos_test_image.tar.xz; ' % download_path)
    if self.log_level != 'verbose':
      self._logger.LogOutput('CMD: %s' % command)
      print('(Removing file chromiumos_test_image.tar.xz.)')
    # try removing file, its ok to have an error, print if encountered
    retval = self._ce.RunCommand(command)
    if retval != 0:
      print('(Warning: Could not remove file chromiumos_test_image.tar.xz .)')

  def DownloadSingleFile(self, chromeos_root, build_id, package_file_name):
    # Verify if package files exist
    status = 0
    gs_package_name = ('gs://chromeos-image-archive/%s/%s' %
                       (build_id, package_file_name))
    gsutil_cmd = os.path.join(chromeos_root, GS_UTIL)
    if not test_flag.GetTestMode():
      cmd = '%s ls %s' % (gsutil_cmd, gs_package_name)
      status = self._ce.RunCommand(cmd)
    if status != 0:
      raise MissingFile('Cannot find package file: %s.' % package_file_name)

    if self.log_level == 'average':
      self._logger.LogOutput('Preparing to download %s package to local '
                             'directory.' % package_file_name)

    # Make sure the directory for downloading the package exists.
    download_path = os.path.join(chromeos_root, 'chroot/tmp', build_id)
    package_path = os.path.join(download_path, package_file_name)
    if not os.path.exists(download_path):
      os.makedirs(download_path)

    # Check to see if the package file has already been downloaded.  If not,
    # download it.
    if not os.path.exists(package_path):
      command = '%s cp %s %s' % (gsutil_cmd, gs_package_name, download_path)

      if self.log_level != 'verbose':
        self._logger.LogOutput('CMD: %s' % command)
      status = self._ce.RunCommand(command)
      if status != 0 or not os.path.exists(package_path):
        raise MissingFile('Cannot download package: %s .' % package_path)

  def UncompressSingleFile(self, chromeos_root, build_id, package_file_name,
                           uncompress_cmd):
    # Uncompress file
    download_path = os.path.join(chromeos_root, 'chroot/tmp', build_id)
    command = ('cd %s ; %s %s' %
               (download_path, uncompress_cmd, package_file_name))

    if self.log_level != 'verbose':
      self._logger.LogOutput('CMD: %s' % command)
      print('(Uncompressing file %s .)' % package_file_name)
    retval = self._ce.RunCommand(command)
    if retval != 0:
      raise MissingFile('Cannot uncompress file: %s.' % package_file_name)
    # Remove uncompressed downloaded file
    command = ('cd %s ; rm -f %s' % (download_path, package_file_name))
    if self.log_level != 'verbose':
      self._logger.LogOutput('CMD: %s' % command)
      print('(Removing processed file %s .)' % package_file_name)
    # try removing file, its ok to have an error, print if encountered
    retval = self._ce.RunCommand(command)
    if retval != 0:
      print('(Warning: Could not remove file %s .)' % package_file_name)

  def VerifyFileExists(self, chromeos_root, build_id, package_file):
    # Quickly verify if the files are there
    status = 0
    gs_package_name = ('gs://chromeos-image-archive/%s/%s' %
                       (build_id, package_file))
    gsutil_cmd = os.path.join(chromeos_root, GS_UTIL)
    if not test_flag.GetTestMode():
      cmd = '%s ls %s' % (gsutil_cmd, gs_package_name)
      if self.log_level != 'verbose':
        self._logger.LogOutput('CMD: %s' % cmd)
      status = self._ce.RunCommand(cmd)
      if status != 0:
        print('(Warning: Could not find file %s )' % gs_package_name)
        return 1
    # Package exists on server
    return 0

  def DownloadAutotestFiles(self, chromeos_root, build_id):
    # Download autest package files (3 files)
    autotest_packages_name = ('autotest_packages.tar')
    autotest_server_package_name = ('autotest_server_package.tar.bz2')
    autotest_control_files_name = ('control_files.tar')

    download_path = os.path.join(chromeos_root, 'chroot/tmp', build_id)
    # Autotest directory relative path wrt chroot
    autotest_rel_path = os.path.join('/tmp', build_id, 'autotest_files')
    # Absolute Path to download files
    autotest_path = os.path.join(chromeos_root, 'chroot/tmp', build_id,
                                 'autotest_files')

    if not os.path.exists(autotest_path):
      # Quickly verify if the files are present on server
      # If not, just exit with warning
      status = self.VerifyFileExists(chromeos_root, build_id,
                                     autotest_packages_name)
      if status != 0:
        default_autotest_dir = '/mnt/host/source/src/third_party/autotest/files'
        print('(Warning: Could not find autotest packages .)\n'
              '(Warning: Defaulting autotest path to %s .' %
              default_autotest_dir)
        return default_autotest_dir

      # Files exist on server, download and uncompress them
      self.DownloadSingleFile(chromeos_root, build_id, autotest_packages_name)
      self.DownloadSingleFile(chromeos_root, build_id,
                              autotest_server_package_name)
      self.DownloadSingleFile(chromeos_root, build_id,
                              autotest_control_files_name)

      self.UncompressSingleFile(chromeos_root, build_id, autotest_packages_name,
                                'tar -xf ')
      self.UncompressSingleFile(chromeos_root, build_id,
                                autotest_server_package_name, 'tar -jxf ')
      self.UncompressSingleFile(chromeos_root, build_id,
                                autotest_control_files_name, 'tar -xf ')
      # Rename created autotest directory to autotest_files
      command = ('cd %s ; mv autotest autotest_files' % download_path)
      if self.log_level != 'verbose':
        self._logger.LogOutput('CMD: %s' % command)
        print('(Moving downloaded autotest files to autotest_files)')
      retval = self._ce.RunCommand(command)
      if retval != 0:
        raise MissingFile('Could not create directory autotest_files')

    return autotest_rel_path

  def DownloadDebugFile(self, chromeos_root, build_id):
    # Download autest package files (3 files)
    debug_archive_name = 'debug.tgz'

    download_path = os.path.join(chromeos_root, 'chroot/tmp', build_id)
    # Debug directory relative path wrt chroot
    debug_rel_path = os.path.join('/tmp', build_id, 'debug_files')
    # Debug path to download files
    debug_path = os.path.join(chromeos_root, 'chroot/tmp', build_id,
                              'debug_files')

    if not os.path.exists(debug_path):
      # Quickly verify if the file is present on server
      # If not, just exit with warning
      status = self.VerifyFileExists(chromeos_root, build_id,
                                     debug_archive_name)
      if status != 0:
        self._logger.LogOutput('WARNING: Could not find debug archive on gs')
        return ''

      # File exists on server, download and uncompress it
      self.DownloadSingleFile(chromeos_root, build_id, debug_archive_name)

      self.UncompressSingleFile(chromeos_root, build_id, debug_archive_name,
                                'tar -xf ')
      # Extract and move debug files into the proper location.
      debug_dir = 'debug_files/usr/lib'
      command = ('cd %s ; mkdir -p %s; mv debug %s' %
                 (download_path, debug_dir, debug_dir))
      if self.log_level != 'verbose':
        self._logger.LogOutput('CMD: %s' % command)
        print('Moving downloaded debug files to %s' % debug_dir)
      retval = self._ce.RunCommand(command)
      if retval != 0:
        raise MissingFile('Could not create directory %s' %
                          os.path.join(debug_dir, 'debug'))

    return debug_rel_path

  def Run(self, chromeos_root, xbuddy_label, autotest_path, debug_path,
          download_debug):
    build_id = self.GetBuildID(chromeos_root, xbuddy_label)
    image_name = (
        'gs://chromeos-image-archive/%s/chromiumos_test_image.tar.xz' %
        build_id)

    # Verify that image exists for build_id, before attempting to
    # download it.
    status = 0
    if not test_flag.GetTestMode():
      gsutil_cmd = os.path.join(chromeos_root, GS_UTIL)
      cmd = '%s ls %s' % (gsutil_cmd, image_name)
      status = self._ce.RunCommand(cmd)
    if status != 0:
      raise MissingImage('Cannot find official image: %s.' % image_name)

    image_path = self.DownloadImage(chromeos_root, build_id, image_name)
    self.UncompressImage(chromeos_root, build_id)

    if self.log_level != 'quiet':
      self._logger.LogOutput('Using image from %s.' % image_path)

    if autotest_path == '':
      autotest_path = self.DownloadAutotestFiles(chromeos_root, build_id)

    if debug_path == '' and download_debug:
      debug_path = self.DownloadDebugFile(chromeos_root, build_id)

    return image_path, autotest_path, debug_path
