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

from recipe_engine import recipe_api


class SymbolizeApi(recipe_api.RecipeApi):
  """Symbolizes logs."""

  OUTPUT_JSON = 'symbolizer-output.json'
  LOG = 'symbolized_log.txt'

  def __call__(self,
               symbolize_tool,
               llvm_symbolizer,
               data,
               level='debug',
               build_id_dirs=(),
               debug_symbol_gcs_bucket=None,
               symbolizer_output=None,
               json_output=None,
               presentation=None):
    """Invokes zircon's symbolization script to symbolize the given data.

    Args:
      symbolize_tool (Path): The path to the symbolize tool.
      llvm_symbolizer (Path): The path to the llvm_symbolizer tool.
      data (String): Step output.
      level (String): Debug level passed to the symbolize tool.
      build_id_dirs (seq(Path)): A list of build-id directories.
      debug_symbol_gcs_bucket (str): A GCS bucket hosting debug symbols.
      symbolizer_output (Path): The path to save the symbolizer stdout to.
      json_output (Path): The path to save the symbolizer json trigger
        information to.
      presentation (StepPresentation or None): The step presentation to add the
        symbolized logs to.

    Returns:
      Symbolizer output, split into lines.
    """
    assert build_id_dirs or debug_symbol_gcs_bucket,\
        'one of a build-id directory or debug_symbol_gcs_bucket must be supplied'

    presentation = presentation or self.m.step.active_result.presentation
    # Value of llvm-symbolizer-restart-interval chosen to avoid running out of
    # memory on 1-core GCE VMs.
    # TODO(42018): Remove restart flag when fixed.
    symbolize_cmd = [symbolize_tool, '-llvm-symbolizer-restart-interval', '2']

    if level:
      symbolize_cmd.extend(['-level', level])

    for build_id_dir in build_id_dirs:
      symbolize_cmd.extend(['-build-id-dir', build_id_dir])
    if debug_symbol_gcs_bucket:
      # The symbolize tool accepts a "symbol-server" argument which
      # in reality is a GCS bucket hosting debug symbols indexed by build ID.
      symbolize_cmd.extend(['-symbol-server', debug_symbol_gcs_bucket])
      symbolize_cmd.extend(
          ['-symbol-cache', self.m.path['cache'].join('symbol')])

    symbolize_cmd.extend(['-llvm-symbolizer', llvm_symbolizer])
    if json_output:
      # We intentionally avoid using a json output placeholder here because
      # doing so would require loading the entire (possibly massive) symbolizer
      # output json into memory, which can cause OOMs.
      symbolize_cmd.extend(['-json-output', json_output])

    symbolize_result = self.m.step(
        'symbolize logs',
        symbolize_cmd,
        stdin=self.m.raw_io.input(data=data),
        stdout=self.m.raw_io.output(leak_to=symbolizer_output, name=self.LOG),
        step_test_data=lambda: self.m.raw_io.test_api.stream_output(
            'blah\nblah\n'),
        infra_step=True)

    symbolized_lines = symbolize_result.stdout.splitlines()
    if symbolized_lines:
      presentation.logs['symbolized log'] = symbolized_lines

    return symbolized_lines
