# 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
