# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Functions for reading build information from GoogleStorage.

This module contains functions providing access to basic data about
Chrome OS builds:
  * Functions for finding information about the Chrome OS versions
    currently being served by Omaha for various boards/hardware models.
  * Functions for finding information about the firmware delivered by
    any given build of Chrome OS.

The necessary data is stored in JSON files in well-known locations in
GoogleStorage.
"""

import json
import subprocess

import common
from autotest_lib.client.common_lib import utils
from autotest_lib.server import frontend


# _OMAHA_STATUS - URI of a file in GoogleStorage with a JSON object
# summarizing all versions currently being served by Omaha.
#
# The principal data is in an array named 'omaha_data'.  Each entry
# in the array contains information relevant to one image being
# served by Omaha, including the following information:
#   * The board name of the product, as known to Omaha.
#   * The channel associated with the image.
#   * The Chrome and Chrome OS version strings for the image
#     being served.
#
_OMAHA_STATUS = 'gs://chromeos-build-release-console/omaha_status.json'


# _BUILD_METADATA_PATTERN - Format string for the URI of a file in
# GoogleStorage with a JSON object that contains metadata about
# a given build.  The metadata includes the version of firmware
# bundled with the build.
#
_BUILD_METADATA_PATTERN = 'gs://chromeos-image-archive/%s/metadata.json'


# _FIRMWARE_UPGRADE_DENYLIST - a set of boards that are exempt from
# automatic stable firmware version assignment.  This denylist is
# here out of an abundance of caution, on the general principle of "if
# it ain't broke, don't fix it."  Specifically, these are old, legacy
# boards and:
#   * They're working fine with whatever firmware they have in the lab
#     right now.
#   * Because of their age, we can expect that they will never get any
#     new firmware updates in future.
#   * Servo support is spotty or missing, so there's no certainty that
#     DUTs bricked by a firmware update can be repaired.
#   * Because of their age, they are somewhere between hard and
#     impossible to replace.  In some cases, they are also already in
#     short supply.
#
# N.B.  HARDCODED BOARD NAMES ARE EVIL!!!  This denylist uses hardcoded
# names because it's meant to define a list of legacies that will shrivel
# and die over time.
#
# DO NOT ADD TO THIS LIST.  If there's a new use case that requires
# extending the denylist concept, you should find a maintainable
# solution that deletes this code.
#
# TODO(jrbarnette):  When any board is past EOL, and removed from the
# lab, it can be removed from the denylist.  When all the boards are
# past EOL, the denylist should be removed.

_FIRMWARE_UPGRADE_DENYLIST = set([
        'butterfly',
        'daisy',
        'daisy_skate',
        'daisy_spring',
        'lumpy',
        'parrot',
        'parrot_ivb',
        'peach_pi',
        'peach_pit',
        'stout',
        'stumpy',
        'x86-alex',
        'x86-mario',
        'x86-zgb',
])


def _read_gs_json_data(gs_uri):
    """Read and parse a JSON file from GoogleStorage.

    This is a wrapper around `gsutil cat` for the specified URI.
    The standard output of the command is parsed as JSON, and the
    resulting object returned.

    @param gs_uri   URI of the JSON file in GoogleStorage.
    @return A JSON object parsed from `gs_uri`.
    """
    with open('/dev/null', 'w') as ignore_errors:
        sp = subprocess.Popen(['gsutil', 'cat', gs_uri],
                              stdout=subprocess.PIPE,
                              stderr=ignore_errors)
        try:
            json_object = json.load(sp.stdout)
        finally:
            sp.stdout.close()
            sp.wait()
    return json_object


def _read_build_metadata(board, cros_version):
    """Read and parse the `metadata.json` file for a build.

    Given the board and version string for a potential CrOS image,
    find the URI of the build in GoogleStorage, and return a Python
    object for the associated `metadata.json`.

    @param board         Board for the build to be read.
    @param cros_version  Build version string.
    """
    image_path = frontend.format_cros_image_name(board, cros_version)
    return _read_gs_json_data(_BUILD_METADATA_PATTERN % image_path)


def _get_by_key_path(dictdict, key_path):
    """Traverse a sequence of keys in a dict of dicts.

    The `dictdict` parameter is a dict of nested dict values, and
    `key_path` a list of keys.

    A single-element key path returns `dictdict[key_path[0]]`, a
    two-element path returns `dictdict[key_path[0]][key_path[1]]`, and
    so forth.  If any key in the path is not found, return `None`.

    @param dictdict   A dictionary of nested dictionaries.
    @param key_path   The sequence of keys to look up in `dictdict`.
    @return The value found by successive dictionary lookups, or `None`.
    """
    value = dictdict
    for key in key_path:
        value = value.get(key)
        if value is None:
            break
    return value


def _get_model_firmware_versions(metadata_json, board):
    """Get the firmware version for all models in a unibuild board.

    @param metadata_json    The metadata_json dict parsed from the
                            metadata.json file generated by the build.
    @param board            The board name of the unibuild.
    @return If the board has no models, return {board: None}.
            Otherwise, return a dict mapping each model name to its
            firmware version.
    """
    model_firmware_versions = {}
    key_path = ['board-metadata', board, 'models']
    model_versions = _get_by_key_path(metadata_json, key_path)

    if model_versions is not None:
        for model, fw_versions in model_versions.iteritems():
            fw_version = (fw_versions.get('main-readwrite-firmware-version') or
                          fw_versions.get('main-readonly-firmware-version'))
            model_firmware_versions[model] = fw_version
    else:
        model_firmware_versions[board] = None

    return model_firmware_versions


def get_omaha_version_map():
    """Convert omaha versions data to a versions mapping.

    Returns a dictionary mapping board names to the currently preferred
    version for the Beta channel as served by Omaha.  The mappings are
    provided by settings in the JSON object read from `_OMAHA_STATUS`.

    The board names are the names as known to Omaha:  If the board name
    in the AFE contains '_', the corresponding Omaha name uses '-'
    instead.  The boards mapped may include boards not in the list of
    managed boards in the lab.

    @return A dictionary mapping Omaha boards to Beta versions.
    """
    def _entry_valid(json_entry):
        return json_entry['channel'] == 'beta'

    def _get_omaha_data(json_entry):
        board = json_entry['board']['public_codename']
        milestone = json_entry['milestone']
        build = json_entry['chrome_os_version']
        version = 'R%d-%s' % (milestone, build)
        return (board, version)

    omaha_status = _read_gs_json_data(_OMAHA_STATUS)
    return dict(_get_omaha_data(e) for e in omaha_status['omaha_data']
                    if _entry_valid(e))


def get_omaha_upgrade(omaha_map, board, version):
    """Get the later of a build in `omaha_map` or `version`.

    Read the Omaha version for `board` from `omaha_map`, and compare it
    to `version`.  Return whichever version is more recent.

    N.B. `board` is the name of a board as known to the AFE.  Board
    names as known to Omaha are different; see
    `get_omaha_version_map()`, above.  This function is responsible
    for translating names as necessary.

    @param omaha_map  Mapping of Omaha board names to preferred builds.
    @param board      Name of the board to look up, as known to the AFE.
    @param version    Minimum version to be accepted.

    @return Returns a Chrome OS version string in standard form
            R##-####.#.#.  Will return `None` if `version` is `None` and
            no Omaha entry is found.
    """
    omaha_version = omaha_map.get(board.replace('_', '-'))
    if version is None:
        return omaha_version
    if omaha_version is not None:
        if utils.compare_versions(version, omaha_version) < 0:
            return omaha_version
    return version


def get_firmware_versions(board, cros_version):
    """Get the firmware versions for a given board and CrOS version.

    During the CrOS auto-update process, the system will check firmware
    on the target device, and update that firmware if needed.  This
    function finds the version string of the firmware that would be
    installed from a given CrOS build.

    A build may have firmware for more than one hardware model, so the
    returned value is a dictionary mapping models to firmware version
    strings.

    The returned firmware version value will be `None` if the build
    isn't found in storage, if there is no firmware found for the build,
    or if the board is denylisted from firmware updates in the test
    lab.

    @param board          The board for the firmware version to be
                          determined.
    @param cros_version   The CrOS version bundling the firmware.
    @return A dict mapping from board to firmware version string for
            non-unibuild board, or a dict mapping from models to firmware
            versions for a unibuild board (see return type of
            _get_model_firmware_versions)
    """
    if board in _FIRMWARE_UPGRADE_DENYLIST:
        return {board: None}
    try:
        metadata_json = _read_build_metadata(board, cros_version)
        unibuild = bool(_get_by_key_path(metadata_json, ['unibuild']))
        if unibuild:
            return _get_model_firmware_versions(metadata_json, board)
        else:
            key_path = ['board-metadata', board, 'main-firmware-version']
            return {board: _get_by_key_path(metadata_json, key_path)}
    except Exception as e:
        # TODO(jrbarnette): If we get here, it likely means that the
        # build for this board doesn't exist.  That can happen if a
        # board doesn't release on the Beta channel for at least 6 months.
        #
        # We can't allow this error to propagate up the call chain
        # because that will kill assigning versions to all the other
        # boards that are still OK, so for now we ignore it.  Probably,
        # we should do better.
        return {board: None}
