# Copyright 2020 The Fuchsia 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 os
from recipe_engine import recipe_api


class DebugSymbolsApi(recipe_api.RecipeApi):
  """APIs for fetching and uploading debug symbols."""

  def fetch_and_upload(self, project, checkout_root, import_in, remote,
                       project_dir, packages, debug_symbol_attribute,
                       debug_symbol_gcs_buckets):
    """
    Fetch debug symbol archives, unpack them, and upload debug symbols.

    Args:
      project (str): Jiri remote manifest project.
      checkout_root (Path): Path to the location where the source code was
        already checked out.
      import_in (str): Path to the edited manifest relative to $project
        containing debug symbol packages.
      remote (str): Remote manifest repository.
      project_dir (Path): Project root path of $import_in.
      packages (seq(str)): The list of CIPD packages updated in $import_in.
      debug_symbol_attribute (str): Jiri attribute to match debug symbol packages.
      debug_symbol_gcs_buckets (seq(str)): GCS buckets to upload debug symbols to.
    """
    with self.m.context(infra_steps=True):
      self.m.jiri.init(
          use_lock_file=True,
          attributes=(debug_symbol_attribute,),
      )
      # Fetch debug symbol packages using locally edited manifest.
      self.m.jiri.import_manifest(
          manifest=import_in,
          remote=remote,
          name=project,
      )
      self.m.jiri.fetch_packages(local_manifest=True)

    with self.m.step.nest('build'):
      gn_results = self.m.build.gen(
          checkout_root=checkout_root,
          fuchsia_build_dir=checkout_root.join('out', 'default'),
          target='x64',
          build_type='debug',
          product='products/bringup.gni',
          # //bundles:infratools is necessary to build upload_debug_symbols.
          packages=['//bundles:infratools'],
      )

      upload_debug_symbols_target = os.path.relpath(
          str(gn_results.tool('upload_debug_symbols')),
          str(gn_results.fuchsia_build_dir),
      )
      self.m.build.ninja(
          checkout_root=checkout_root,
          gn_results=gn_results,
          build_zircon=False,
          targets=[upload_debug_symbols_target],
      )

    build_id_dirs = []
    for package in packages:
      # Find archives for each debug symbol package.
      with self.m.context(cwd=project_dir):
        package_def = self.m.jiri.read_manifest_element(
            manifest=import_in,
            element_type='package',
            element_name=package,
        )
      # Skip non debug symbol packages.
      if debug_symbol_attribute not in package_def.get('attributes', ''):
        continue

      package_path = checkout_root.join(package_def['path'])
      archives = self.m.file.glob_paths(
          name='find archives for %s' % package,
          source=package_path,
          pattern='**/*.tar.bz2',
          test_data=(package_path.join('symbols.tar.bz2'),),
      )

      # Unpack archives into .build-id dirs.
      for archive in archives:
        # Extract API requires a unique, non-existent directory.
        archive_basename = os.path.basename(self.m.path.abspath(archive))
        output_dir = checkout_root.join(package, archive_basename)
        self.m.archive.extract(
            step_name='extract %s' % archive,
            archive_file=archive,
            output=output_dir,
        )
        build_id_dirs.append(output_dir)

    for debug_symbol_gcs_bucket in debug_symbol_gcs_buckets:
      self.m.upload_debug_symbols(
          step_name='upload debug symbols',
          upload_debug_symbols_path=gn_results.tool('upload_debug_symbols'),
          bucket=debug_symbol_gcs_bucket,
          build_id_dirs=build_id_dirs,
      )
