# -*- coding: utf-8 -*-
# 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.

"""Module to manage local build state."""

from __future__ import print_function

import json
import sys

from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import pformat


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


class BuildSummary(object):
  """Summarizes a build state without any external references.

  This is basically a dictionary that can convert itself back and forth from
  JSON, but it provides the convenience of attribute-based access instead of
  carrying around dictionary key constants.

  Attributes:
    build_number: The build number of this build, as passed in with
        --buildnumber, or 0 if --buildnumber wasn't passed.
    buildbucket_id: The buildbucket id of this build, as passed in with
        --buildbucket-id, or 0 if --buildbucket-id wasn't passed.
    master_build_id: The CIDB id of the associated master build if there is one,
        or 0 if there isn't one.
    status: One of the status constants from
        chromite.lib.constants.BUILDER_ALL_STATUSES
    buildroot_layout: Version of the buildroot layout.
    branch: Name of the branch this repository is associated with.
    distfiles_ts: Float unix timestamp recording the last time the distfiles
        cache was cleaned.
  """

  # List of attributes that should be saved and restored to represent
  # this object.  We use an explicit list instead of vars() so that future
  # additions can be handled explicitly.
  _PERSIST_ATTRIBUTES = ('build_number', 'buildbucket_id', 'master_build_id',
                         'status', 'buildroot_layout', 'branch', 'distfiles_ts')

  def __init__(self, build_number=0, buildbucket_id=0, master_build_id=0,
               status=constants.BUILDER_STATUS_MISSING,
               buildroot_layout=0, branch='', distfiles_ts=None):
    self.build_number = build_number
    self.buildbucket_id = buildbucket_id
    self.master_build_id = master_build_id
    self.status = status
    self.buildroot_layout = buildroot_layout
    self.branch = branch
    self.distfiles_ts = distfiles_ts

  def __eq__(self, other):
    for a in self._PERSIST_ATTRIBUTES:
      if hasattr(other, a) != hasattr(self, a):
        return False
      if getattr(other, a) != getattr(self, a):
        return False
    return True

  def __repr__(self):
    return 'BuildSummary(%s)' % self.to_json()

  def from_json(self, raw_json):
    """Merge the state encoded in |raw_json| into this object.

    Unknown keys will be ignored (with a warning).  Values for missing keys will
    remain unchanged.

    Args:
      raw_json: String containing valid JSON representing a BuildSummary.

    Raises:
      ValueError: |raw_json| is not valid JSON.
    """
    new_state = json.loads(raw_json)
    for key, val in new_state.items():
      if key in self._PERSIST_ATTRIBUTES:
        setattr(self, key, val)
      else:
        logging.warning('Ignoring unrecognized JSON key "%s"', key)

    if self.status not in constants.BUILDER_ALL_STATUSES:
      logging.warning('Ingoring unknown build status "%s"', self.status)
      self.status = constants.BUILDER_STATUS_MISSING

  def to_json(self):
    """Serialize this object to JSON.

    Attributes that have an empty/zero value are omitted from the output.  The
    output of this function can be passed to from_json() to get back another
    BuildSummary with the same values.

    Returns:
      A string containing a JSON-encoded representation of this object.
    """
    state = {}
    for a in self._PERSIST_ATTRIBUTES:
      val = getattr(self, a)
      if val:
        state[a] = getattr(self, a)
    return pformat.json(state, compact=True)

  def is_valid(self):
    """Indicate whether this object has a valid status."""
    return self.status != constants.BUILDER_STATUS_MISSING

  def build_description(self):
    """Get a human-readable description of which build id is set.

    If multiple fields are set, buildbucket is preferred.  The result can be
    used for logging or display, but should not be parsed for database lookups.

    Returns:
      String describing which build id is set, or "local build" if none are set.
    """
    if self.buildbucket_id:
      return 'buildbucket_id=%s' % self.buildbucket_id
    if self.build_number:
      return 'build_number=%s' % self.build_number
    return 'local build'
