# Copyright 2019 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Evergreen implementation of Starboard launcher abstraction."""

import logging
import os
import shutil

from starboard.tools import abstract_launcher
from starboard.tools import paths

_BASE_STAGING_DIRECTORY = 'evergreen_staging'
_CRASHPAD_TARGET = 'crashpad_handler'
_DEFAULT_LOADER_TARGET = 'elf_loader_sandbox'


class Launcher(abstract_launcher.AbstractLauncher):
  """Class for launching Evergreen targets on arbitrary platforms.

  This Evergreen launcher leverages the platform-specific launchers to start the
  Evergreen loader on a particular device. A staging directory is built that
  resembles a typical install directory, with the Evergreen target and its
  content included in the Evergreen loader's content. The platform-specific
  launcher, given command-line switches to tell the Evergreen loader where the
  Evergreen target and its content are, can run the loader without needing to
  know about Evergreen per-se.

  The Evergreen launcher does not require its own implementation for many
  abstract launcher methods and trampolines them to the platform-specific
  launcher.
  """

  def __init__(self, platform, target_name, config, device_id, **kwargs):
    # TODO: Remove this injection of 'detect_leaks=0' once the memory leaks when
    #       running executables in Evergreen mode have been resolved.
    env_variables = kwargs.get('env_variables') or {}
    asan_options = env_variables.get('ASAN_OPTIONS', '')
    asan_options = [
        opt for opt in asan_options.split(':') if 'detect_leaks' not in opt
    ]
    asan_options.append('detect_leaks=0')
    env_variables['ASAN_OPTIONS'] = ':'.join(asan_options)
    kwargs['env_variables'] = env_variables

    # pylint: disable=super-with-arguments
    super().__init__(platform, target_name, config, device_id, **kwargs)

    self.loader_platform = kwargs.get('loader_platform')
    if not self.loader_platform:
      raise ValueError('|loader_platform| cannot be |None|.')

    self.loader_config = kwargs.get('loader_config')
    if not self.loader_config:
      raise ValueError('|loader_config| cannot be |None|.')

    self.loader_target = kwargs.get('loader_target')
    if not self.loader_target:
      self.loader_target = _DEFAULT_LOADER_TARGET

    self.loader_out_directory = kwargs.get('loader_out_directory')
    if not self.loader_out_directory:
      self.loader_out_directory = paths.BuildOutputDirectory(
          self.loader_platform, self.loader_config)

    self.use_compressed_library = kwargs.get('use_compressed_library')

    # The relationship of loader platforms and configurations to evergreen
    # platforms and configurations is many-to-many. We need a separate directory
    # for each of them, i.e. linux-x64x11_debug__evergreen-x64_gold.
    loader_build_name = f'{self.loader_platform}_{self.loader_config}'
    target_build_name = f'{platform}_{config}'
    self.combined_config = f'{loader_build_name}__{target_build_name}'

    self.staging_directory = os.path.join(
        os.path.dirname(self.out_directory), _BASE_STAGING_DIRECTORY,
        self.combined_config)

    # TODO: Figure out a place for the launcher to do this prep work that is not
    # part of the constructor.
    self._StageTargetsAndContents()

    # Ensure the path, relative to the content of the ELF Loader, to the
    # Evergreen target and its content are passed as command line switches.
    library_path_value = os.path.join('app', self.target_name, 'lib',
                                      f'lib{self.target_name}')
    library_path_param = f'--evergreen_library={library_path_value}'
    if self.use_compressed_library:
      if self.target_name != 'cobalt':
        raise ValueError(
            '|use_compressed_library| only expected with |target_name| cobalt')
      library_path_param += '.lz4'
    else:
      library_path_param += '.so'

    target_command_line_params = [
        library_path_param,
        f'--evergreen_content=app/{self.target_name}/content'
    ]

    if self.target_command_line_params:
      target_command_line_params.extend(self.target_command_line_params)

    self.launcher = abstract_launcher.LauncherFactory(
        self.loader_platform,
        self.loader_target,
        self.loader_config,
        device_id,
        target_params=target_command_line_params,
        output_file=self.output_file,
        out_directory=self.staging_directory,
        coverage_directory=self.coverage_directory,
        env_variables=self.env_variables,
        log_targets=False)

  def Run(self):
    """Redirects to the ELF Loader platform's abstract loader implementation."""

    return_code = 1

    logging.info('-' * 32)
    logging.info('Starting to run target: %s', self.target_name)
    logging.info('=' * 32)

    try:

      return_code = self.launcher.Run()
    except Exception:  # pylint: disable=broad-except
      logging.exception('Error occurred while running test.')

    logging.info('-' * 32)
    logging.info('Finished running target: %s', self.target_name)
    logging.info('=' * 32)

    return return_code

  def Kill(self):
    """Redirects to the ELF Loader platform's abstract loader implementation."""
    self.launcher.Kill()

  def _StageTargetsAndContents(self):
    """Stage targets and their contents in our staging directory.

    The existing launcher infrastructure expects a specific directory structure
    regardless of whether or not we are running locally:

             platform:    raspi-2          raspi-2_devel
             config:      devel             +-- install
             target_name: nplb                   +-- nplb
                                                      +-- content
                                                      +-- nplb

    This function effectively builds a directory structure that matches both of
    these expectations while minimizing the hard copies made.

    Note: The Linux launcher does not yet look in the install directory and
          instead runs the target from the top of its out-directory. This will
          be changed in the future.
    """
    if os.path.exists(self.staging_directory):
      shutil.rmtree(self.staging_directory)
    os.makedirs(self.staging_directory)

    # TODO(b/267568637): Make the Linux launcher run from the install_directory.
    if 'linux' in self.loader_platform:
      self._StageTargetsAndContentsLinux()
    else:
      self._StageTargetsAndContentsRaspi()

  def _StageTargetsAndContentsLinux(self):
    """Stage targets and their contents for GN builds for Linux platforms."""
    content_subdir = os.path.join('usr', 'share', 'cobalt')

    # Copy loader content and binaries
    loader_install_path = os.path.join(self.loader_out_directory, 'install')

    loader_content_src = os.path.join(loader_install_path, content_subdir)
    loader_content_dst = os.path.join(self.staging_directory, 'content')
    shutil.copytree(loader_content_src, loader_content_dst)

    loader_target_src = os.path.join(loader_install_path, 'bin',
                                     self.loader_target)
    loader_target_dst = os.path.join(self.staging_directory, self.loader_target)
    shutil.copy(loader_target_src, loader_target_dst)

    crashpad_target_src = os.path.join(loader_install_path, 'bin',
                                       _CRASHPAD_TARGET)
    crashpad_target_dst = os.path.join(self.staging_directory, _CRASHPAD_TARGET)
    shutil.copy(crashpad_target_src, crashpad_target_dst)

    # Copy target content and binary
    target_install_path = os.path.join(self.out_directory, 'install')
    target_staging_dir = os.path.join(self.staging_directory, 'content', 'app',
                                      self.target_name)

    target_content_src = os.path.join(target_install_path, content_subdir)
    target_content_dst = os.path.join(target_staging_dir, 'content')
    shutil.copytree(target_content_src, target_content_dst)

    shlib_name = f'lib{self.target_name}'
    shlib_name += '.lz4' if self.use_compressed_library else '.so'
    target_binary_src = os.path.join(target_install_path, 'lib', shlib_name)
    target_binary_dst = os.path.join(target_staging_dir, 'lib', shlib_name)
    os.makedirs(os.path.join(target_staging_dir, 'lib'))
    shutil.copy(target_binary_src, target_binary_dst)

  def _StageTargetsAndContentsRaspi(self):
    """Stage targets and their contents for GN builds for Raspi platforms."""
    # TODO(b/218889313): `content` is hardcoded on raspi and must be in the same
    # directory as the binaries.
    if 'raspi' in self.loader_platform:
      content_subdir = 'content'
      bin_subdir = ''
    else:
      content_subdir = os.path.join('usr', 'share', 'cobalt')
      bin_subdir = 'bin'

    # Copy loader content and binaries to
    loader_install_path = os.path.join(self.loader_out_directory, 'install')
    # raspi is a packaged platform and the loader target is the staging target.
    staging_directory_loader = os.path.join(self.staging_directory, 'install',
                                            self.loader_target)

    loader_content_src = os.path.join(loader_install_path, content_subdir)
    loader_content_dst = os.path.join(staging_directory_loader, 'content')
    shutil.copytree(loader_content_src, loader_content_dst)

    loader_binary_src = os.path.join(loader_install_path, bin_subdir)
    loader_target_src = os.path.join(loader_binary_src, self.loader_target,
                                     self.loader_target)
    loader_target_dst = os.path.join(staging_directory_loader,
                                     self.loader_target)
    shutil.copy(loader_target_src, loader_target_dst)

    crashpad_target_src = os.path.join(loader_binary_src, _CRASHPAD_TARGET,
                                       _CRASHPAD_TARGET)
    crashpad_target_dst = os.path.join(staging_directory_loader,
                                       _CRASHPAD_TARGET)
    shutil.copy(crashpad_target_src, crashpad_target_dst)

    # Copy target content and binary
    target_install_path = os.path.join(self.out_directory, 'install')
    target_staging_dir = os.path.join(staging_directory_loader, 'content',
                                      'app', self.target_name)
    os.makedirs(target_staging_dir)

    # TODO(b/218889313): Reset the content path for the evergreen artifacts.
    content_subdir = os.path.join('usr', 'share', 'cobalt')
    target_content_src = os.path.join(target_install_path, content_subdir)
    target_content_dst = os.path.join(target_staging_dir, 'content')
    shutil.copytree(target_content_src, target_content_dst)

    shlib_name = f'lib{self.target_name}'
    shlib_name += '.lz4' if self.use_compressed_library else '.so'
    target_binary_src = os.path.join(target_install_path, 'lib', shlib_name)
    target_binary_dst = os.path.join(target_staging_dir, 'lib', shlib_name)
    os.makedirs(os.path.join(target_staging_dir, 'lib'))
    shutil.copy(target_binary_src, target_binary_dst)

  def SupportsSuspendResume(self):
    return self.launcher.SupportsSuspendResume()

  def SendResume(self):
    return self.launcher.SendResume()

  def SendSuspend(self):
    return self.launcher.SendSuspend()

  def SendConceal(self):
    return self.launcher.SendConceal()

  def SendFocus(self):
    return self.launcher.SendFocus()

  def SendFreeze(self):
    return self.launcher.SendFreeze()

  def SendStop(self):
    return self.launcher.SendStop()

  def SupportsDeepLink(self):
    return self.launcher.SupportsDeepLink()

  def SendDeepLink(self, link):
    return self.launcher.SendDeepLink(link)

  def GetStartupTimeout(self):
    return self.launcher.GetStartupTimeout()

  def GetHostAndPortGivenPort(self, port):
    return self.launcher.GetHostAndPortGivenPort(port)

  def GetTargetPath(self):
    return self.launcher.GetTargetPath()

  def GetDeviceIp(self):
    return self.launcher.GetDeviceIp()

  def GetDeviceOutputPath(self):
    return self.launcher.GetDeviceOutputPath()
