#!/usr/bin/env python
# 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.

'''Gatherer for <structure type="chrome_scaled_image">.
'''

import os
import struct

from grit import exception
from grit import lazy_re
from grit import util
from grit.gather import interface


_PNG_SCALE_CHUNK = '\0\0\0\0csCl\xc1\x30\x60\x4d'


def _RescaleImage(data, from_scale, to_scale):
  if from_scale != to_scale:
    assert from_scale == 100
    # Rather than rescaling the image we add a custom chunk directing Chrome to
    # rescale it on load. Just append it to the PNG data since
    # _MoveSpecialChunksToFront will move it later anyway.
    data += _PNG_SCALE_CHUNK
  return data


_PNG_MAGIC = '\x89PNG\r\n\x1a\n'

'''Mandatory first chunk in order for the png to be valid.'''
_FIRST_CHUNK = 'IHDR'

'''Special chunks to move immediately after the IHDR chunk. (so that the PNG
remains valid.)
'''
_SPECIAL_CHUNKS = frozenset('csCl npTc'.split())

'''Any ancillary chunk not in this list is deleted from the PNG.'''
_ANCILLARY_CHUNKS_TO_LEAVE = frozenset(
    'bKGD cHRM gAMA iCCP pHYs sBIT sRGB tRNS'.split())


def _MoveSpecialChunksToFront(data):
  '''Move special chunks immediately after the IHDR chunk (so that the PNG
  remains valid). Also delete ancillary chunks that are not on our whitelist.
  '''
  first = [_PNG_MAGIC]
  special_chunks = []
  rest = []
  for chunk in _ChunkifyPNG(data):
    type = chunk[4:8]
    critical = type < 'a'
    if type == _FIRST_CHUNK:
      first.append(chunk)
    elif type in _SPECIAL_CHUNKS:
      special_chunks.append(chunk)
    elif critical or type in _ANCILLARY_CHUNKS_TO_LEAVE:
      rest.append(chunk)
  return ''.join(first + special_chunks + rest)


def _ChunkifyPNG(data):
  '''Given a PNG image, yield its chunks in order.'''
  assert data.startswith(_PNG_MAGIC)
  pos = 8
  while pos != len(data):
    length = 12 + struct.unpack_from('>I', data, pos)[0]
    assert 12 <= length <= len(data) - pos
    yield data[pos:pos+length]
    pos += length


def _MakeBraceGlob(strings):
  '''Given ['foo', 'bar'], return '{foo,bar}', for error reporting.
  '''
  if len(strings) == 1:
    return strings[0]
  else:
    return '{' + ','.join(strings) + '}'


class ChromeScaledImage(interface.GathererBase):
  '''Represents an image that exists in multiple layout variants
  (e.g. "default", "touch") and multiple scale variants
  (e.g. "100_percent", "200_percent").
  '''

  split_context_re_ = lazy_re.compile(r'(.+)_(\d+)_percent\Z')

  def _FindInputFile(self):
    output_context = self.grd_node.GetRoot().output_context
    match = self.split_context_re_.match(output_context)
    if not match:
      raise exception.MissingMandatoryAttribute(
          'All <output> nodes must have an appropriate context attribute'
          ' (e.g. context="touch_200_percent")')
    req_layout, req_scale = match.group(1), int(match.group(2))

    layouts = [req_layout]
    try_default_layout = self.grd_node.GetRoot().fallback_to_default_layout
    if try_default_layout and 'default' not in layouts:
      layouts.append('default')

    # TODO(tdanderson): Search in descending order of all image scales
    #                   instead of immediately falling back to 100.
    #                   See crbug.com/503643.
    scales = [req_scale]
    try_low_res = self.grd_node.FindBooleanAttribute(
        'fallback_to_low_resolution', default=False, skip_self=False)
    if try_low_res and 100 not in scales:
      scales.append(100)

    for layout in layouts:
      for scale in scales:
        dir = '%s_%s_percent' % (layout, scale)
        path = os.path.join(dir, self.rc_file)
        if os.path.exists(self.grd_node.ToRealPath(path)):
          return path, scale, req_scale

    if not try_default_layout:
      # The file was not found in the specified output context and it was
      # explicitly indicated that the default context should not be searched
      # as a fallback, so return an empty path.
      return None, 100, req_scale

    # The file was found in neither the specified context nor the default
    # context, so raise an exception.
    dir = "%s_%s_percent" % (_MakeBraceGlob(layouts),
                             _MakeBraceGlob(map(str, scales)))
    raise exception.FileNotFound(
        'Tried ' + self.grd_node.ToRealPath(os.path.join(dir, self.rc_file)))

  def GetInputPath(self):
    path, scale, req_scale = self._FindInputFile()
    return path

  def Parse(self):
    pass

  def GetTextualIds(self):
    return [self.extkey]

  def GetData(self, *args):
    path, scale, req_scale = self._FindInputFile()
    if path is None:
      return None

    data = util.ReadFile(self.grd_node.ToRealPath(path), util.BINARY)
    data = _RescaleImage(data, scale, req_scale)
    data = _MoveSpecialChunksToFront(data)
    return data

  def Translate(self, *args, **kwargs):
    return self.GetData()
