# Copyright (c) 2012 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.

"""Presubmit script for Chromium browser resources.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl/git cl, and see
http://www.chromium.org/developers/web-development-style-guide for the rules
we're checking against here.
"""


import os
import struct


class InvalidPNGException(Exception):
  pass


class ResourceScaleFactors(object):
  """Verifier of image dimensions for Chromium resources.

  This class verifies the image dimensions of resources in the various
  resource subdirectories.

  Attributes:
      paths: An array of tuples giving the folders to check and their
          relevant scale factors. For example:

          [(100, 'default_100_percent'), (200, 'default_200_percent')]
  """

  def __init__(self, input_api, output_api, paths):
    """ Initializes ResourceScaleFactors with paths."""
    self.input_api = input_api
    self.output_api = output_api
    self.paths = paths

  def RunChecks(self):
    """Verifies the scale factors of resources being added or modified.

    Returns:
        An array of presubmit errors if any images were detected not
        having the correct dimensions.
    """
    def ImageSize(filename):
      with open(filename, 'rb', buffering=0) as f:
        data = f.read(24)
      if data[:8] != '\x89PNG\r\n\x1A\n' or data[12:16] != 'IHDR':
        raise InvalidPNGException
      return struct.unpack('>ii', data[16:24])

    # Returns a list of valid scaled image sizes. The valid sizes are the
    # floor and ceiling of (base_size * scale_percent / 100). This is equivalent
    # to requiring that the actual scaled size is less than one pixel away from
    # the exact scaled size.
    def ValidSizes(base_size, scale_percent):
      return sorted(set([(base_size * scale_percent) / 100,
                         (base_size * scale_percent + 99) / 100]))

    repository_path = self.input_api.os_path.relpath(
        self.input_api.PresubmitLocalPath(),
        self.input_api.change.RepositoryRoot())
    results = []

    # Check for affected files in any of the paths specified.
    affected_files = self.input_api.AffectedFiles(include_deletes=False)
    files = []
    for f in affected_files:
      for path_spec in self.paths:
        path_root = self.input_api.os_path.join(
            repository_path, path_spec[1])
        if (f.LocalPath().endswith('.png') and
            f.LocalPath().startswith(path_root)):
          # Only save the relative path from the resource directory.
          relative_path = self.input_api.os_path.relpath(f.LocalPath(),
              path_root)
          if relative_path not in files:
            files.append(relative_path)

    corrupt_png_error = ('Corrupt PNG in file %s. Note that binaries are not '
        'correctly uploaded to the code review tool and must be directly '
        'submitted using the dcommit command.')
    for f in files:
      base_image = self.input_api.os_path.join(self.paths[0][1], f)
      if not os.path.exists(base_image):
        results.append(self.output_api.PresubmitError(
            'Base image %s does not exist' % self.input_api.os_path.join(
            repository_path, base_image)))
        continue
      try:
        base_dimensions = ImageSize(base_image)
      except InvalidPNGException:
        results.append(self.output_api.PresubmitError(corrupt_png_error %
            self.input_api.os_path.join(repository_path, base_image)))
        continue
      # Find all scaled versions of the base image and verify their sizes.
      for i in range(1, len(self.paths)):
        image_path = self.input_api.os_path.join(self.paths[i][1], f)
        if not os.path.exists(image_path):
          continue
        # Ensure that each image for a particular scale factor is the
        # correct scale of the base image.
        try:
          scaled_dimensions = ImageSize(image_path)
        except InvalidPNGException:
          results.append(self.output_api.PresubmitError(corrupt_png_error %
              self.input_api.os_path.join(repository_path, image_path)))
          continue
        for dimension_name, base_size, scaled_size in zip(
            ('width', 'height'), base_dimensions, scaled_dimensions):
          valid_sizes = ValidSizes(base_size, self.paths[i][0])
          if scaled_size not in valid_sizes:
            results.append(self.output_api.PresubmitError(
                'Image %s has %s %d, expected to be %s' % (
                self.input_api.os_path.join(repository_path, image_path),
                dimension_name,
                scaled_size,
                ' or '.join(map(str, valid_sizes)))))
    return results
