# 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'
_NATIVE_TARGET_TOOLCHAIN = 'native_target'
_CRASHPAD_EXECUTABLE = '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|.')

    # RDK doesn't use our loader, therefore the test files are stored
    # in the folder named after the target
    if 'rdk' in self.loader_platform:
      kwargs['loader_target'] = self.target_name

    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_file_path=self.coverage_file_path,
        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()
    elif 'raspi' in self.loader_platform:
      self._StageTargetsAndContentsRaspi()
    elif 'rdk' in self.loader_platform:
      self._StageTargetsAndContentsRdk()
    else:
      raise ValueError(f"'{self.loader_platform}' is not recognized")

  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(self.loader_out_directory,
                                       _NATIVE_TARGET_TOOLCHAIN,
                                       _CRASHPAD_EXECUTABLE)
    crashpad_target_dst = os.path.join(self.staging_directory,
                                       _CRASHPAD_EXECUTABLE)
    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(self.loader_out_directory,
                                       _NATIVE_TARGET_TOOLCHAIN,
                                       _CRASHPAD_EXECUTABLE)
    crashpad_target_dst = os.path.join(staging_directory_loader,
                                       _CRASHPAD_EXECUTABLE)
    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 _StageTargetsAndContentsRdk(self):
    """Stage targets and their contents for GN builds for RDK platforms."""
    # The rdk loader always loads libcobalt.so. Hard code target_name to match.
    rdk_target_name = 'cobalt'

    # 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)
    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}.so'
    target_binary_src = os.path.join(self.out_directory, 'install', 'lib',
                                     shlib_name)
    target_binary_dst = os.path.join(target_staging_dir, 'lib',
                                     f'lib{rdk_target_name}.so')

    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()
