# Copyright 2020 The Chromium 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 YamlApi(recipe_api.RecipeApi):
  """Provides functions to parse YAML files."""

  def parse_yaml(self, file_path):
    """parse a yaml file and return its content as a JSON object.

    E.g. api.yaml.parse_yaml(file_path)

        will read yaml file from file_path and converted into a JSON
        object.

    Args:
      * file_path (Path) - The path to the dockerfile.
    """
    return self.m.python(
        'load yaml %s' % file_path,
        self.resource('parse_yaml.py'),
        args=[file_path],
        stdout=self.m.json.output()).stdout

  def _traverse_json(self, json_data, field):
    if isinstance(json_data, dict):
      if field in json_data:
        return json_data[field]
      for key in json_data:
        return_val = self._traverse_json(json_data[key], field)
        if return_val != None:
          return return_val
    if isinstance(json_data, list):
      for item in json_data:
        return_val = self._traverse_json(item, field)
        if return_val != None:
          return return_val
    return None

  def retrieve_field(self, file_path, field_name):
    """retrieve a field from a YAML file and return the first found value
    if it exists. Otherwise return None.

    E.g. api.yaml.retrieve_field(file_path, 'region')

    Args:
      * file_path (Path) - The path to the YAML file.
      * field_name (str) - The name of the field.
    """
    return self._traverse_json(self.parse_yaml(file_path), field_name)
