# Copyright 2018 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 collections

# PatchInput describes the input to a `jiri patch` command. These are decoded from the
# list of JSON objects in a patchfile (see below).
#
# Properties:
#   ref (str): The gerrit change ref (e.g refs/changes/aa/aabbcc/n)
#   host (str): The code review host (e.g. fuchsia-review.googlesource.com)
#   project (str): The patch project (e.g. garnet)
#
# Usage:
#   These inputs are typically specified within a patchfile at the root of a project's
#   directory.  When checking out from a gerrit patchset (i.e. when running on CQ),
#   CheckoutApi will patch any changes listed in this file.
PatchInput = collections.namedtuple('PatchInput', 'ref host project')


class PatchFile(object):
  """A file used to patch one or more changes from unrelated projects into a workspace.

  The PatchFile should contain a list of JSON objects with the following structure:

    [
        {
            "ref": "refs/changes/56/123456/3",
            "host": "fuchsia-review.googlesource.com",
            "project": "project",
        }
    ]
  """

  @staticmethod
  def from_json(js):
    """Unmarshals a PatchFile from JSON"""
    patch_inputs = []
    for js_object in js:
      patch_inputs.append(PatchInput(**js_object))

    return PatchFile(patch_inputs)

  def __init__(self, patch_inputs):
    self.patch_inputs = patch_inputs

  @property
  def inputs(self):
    return self.patch_inputs

  def validate(self, gerrit_change):
    """Verifies the following about this PatchFile:

    1. No input overwrites the Gerrit change that is currently being tested.
    2. No two inputs patch over one another.

    Returns:
        A ValueError that should be raised as a StepFailure, if validation fails. Else
        None.
    """

    def create_key(project, host):
      """Produces a unique ID for a project + host combination."""
      return '%s/%s' % (project, host)

    # Maps validated PatchInput keys to their PatchInputs.
    validated = {}

    # The key for the original Gerrit change that is being tested.
    gerrit_patch_key = create_key(gerrit_change.project, gerrit_change.host)

    for patch_input in self.patch_inputs:
      patch_key = create_key(patch_input.project, patch_input.host)

      # User cannot use patches.json to overwrite the original gerrit change.
      if patch_key == gerrit_patch_key:
        return ValueError((
            'This patch overwrites the original gerrit change: %s\n'
            'Inline this patch into the change instead of specifying in patches.json'
        ) % str(patch_input))

      # User cannot patch multiple changes to the same project. Those changes should
      # be tested locally.
      if validated.get(patch_key, None):
        return ValueError((
            'Found patch that ovewrites a previous patch. These changes should be'
            'tested together locally instead of through patches.json:\n'
            'Original:  %(original)s\nDuplicate: %(duplicate)s.') % dict(
                original=str(validated[patch_key]),
                duplicate=str(patch_input),
            ))

      validated[patch_key] = patch_input
